﻿using AbpApplication.Expand;
using AbpEntityFrameworkcore.DbContext;
using AbpToDomain.EntityInfo;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using NStandard;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using AbpApplication.InPut;
using Application.Expand;
using AbpApplication.Dto;
using AbpToDomain.View;
using Volo.Abp.Users;
using Microsoft.AspNetCore.SignalR.Client;
using SingalR.Client;
using AbpApplication.Flurl;
using Newtonsoft.Json;
using AbpEntityFrameworkcore;
using OfficeOpenXml;
using Microsoft.AspNetCore.Http;
using System.Data;
using LinqSharp;
using Microsoft.Extensions.Caching.Distributed;
using TaskDescribe = AbpApplication.Flurl.TaskDescribe;
using Tasks = AbpApplication.Flurl.Tasks;
using Mesosphere.InPut;
using MediatR;
using LinqSharp.EFCore.Infrastructure;
using Microsoft.Data.SqlClient;
using S7.Net.Types;
using DateTime = System.DateTime;

namespace AbpApplication.AppServices
{
    ///<inheritdoc/>
    public class BaseService : ApplicationService, IBaseService,INotificationHandler<PostNotification>
    {

        private readonly IRepository<Box> Box_res;
        private readonly IRepository<BoxGrid> BoxGrid_res;
        private readonly IRepository<NeetOutMaterial> NeetOutMaterial_res;
        private readonly IRepository<TaskOrder> TaskOrder_res;
        private readonly IRepository<Warehouse> Warehouse_res;
        private readonly IRepository<WarehouseLine> WarehouseLine_res;
        private readonly IRepository<MaterialBase> MaterialBase_res;
        private readonly IRepository<Inlethouse> Inlethouse_res;
        private readonly IRepository<InlethouseLine> Inlethouseline_res;
        private readonly IRepository<lognote> LogNote_res;
        private readonly IRepository<MaterialProperty> MaterialProperty_res;
        private readonly IRepository<BoxPosition> BoxPosition_res;
        private readonly IRepository<BoxType> BinType_res;
        private readonly IRepository<PutInOrder> PutInOrder_res;
        private readonly IRepository<PutOutOrder> PutOutOrder_res;
        private readonly IRepository<SowingWall> SowingWall_res;
        private readonly IRepository<SowingWallLine> SowingWallLine_res;
        private readonly ICurrentUser User;
        private readonly IToOutSideInterFace toOutSideInterFace;
        private readonly IRepository<MoveContainerInfo> MoveContainerInfo_res;
        private readonly IRepository<CustomOutRep> CustomOutRep_res;
        private readonly IRepository<CustomCheckList> CustomCheckList_res;
        private readonly IMediator Mediator;

        private readonly MyDbContext context;
        private readonly ILoginHelper loginHelper;
        private readonly IDistributedCache cache;
        public BaseService(
            IRepository<Box> box_res,
            IRepository<BoxGrid> boxGrid_res,
            IRepository<Warehouse> warehouse_res,
            IRepository<WarehouseLine> warehouseLine_res,
            IRepository<MaterialBase> materialBase_res,
            MyDbContext context,
            IRepository<NeetOutMaterial> neetOutMaterial_res,
            IRepository<Inlethouse> inlethouse_res,
            IRepository<InlethouseLine> inlethouseline_res,
            IRepository<TaskOrder> taskOrder_res,
            ILoginHelper loginHelper,
            IRepository<lognote> logNote_res,
            IRepository<MaterialProperty> materialProperty_res,
            IRepository<BoxPosition> boxPosition_res,
            IRepository<BoxType> binType_res,
            IRepository<PutInOrder> putInOrder_res,
            IRepository<PutOutOrder> putOutOrder_res,
            ICurrentUser user,
            IRepository<SowingWall> sowingWall_res,
            IRepository<SowingWallLine> sowingWallLine_res,
            IToOutSideInterFace toOutSideInterFace,
            IRepository<MoveContainerInfo> moveContainerInfo_res,
            IRepository<CustomOutRep> customOutRep_res,
            IDistributedCache cache,
            IRepository<CustomCheckList> customCheckList_res,
            IMediator mediator)
        {
            Box_res = box_res;
            BoxGrid_res = boxGrid_res;
            Warehouse_res = warehouse_res;
            WarehouseLine_res = warehouseLine_res;
            MaterialBase_res = materialBase_res;
            this.context = context;
            NeetOutMaterial_res = neetOutMaterial_res;
            Inlethouse_res = inlethouse_res;
            Inlethouseline_res = inlethouseline_res;
            TaskOrder_res = taskOrder_res;
            this.loginHelper = loginHelper;
            LogNote_res = logNote_res;
            MaterialProperty_res = materialProperty_res;
            BoxPosition_res = boxPosition_res;
            BinType_res = binType_res;
            PutInOrder_res = putInOrder_res;
            PutOutOrder_res = putOutOrder_res;
            User = user;
            SowingWall_res = sowingWall_res;
            SowingWallLine_res = sowingWallLine_res;
            this.toOutSideInterFace = toOutSideInterFace;
            MoveContainerInfo_res = moveContainerInfo_res;
            CustomOutRep_res = customOutRep_res;
            this.cache = cache;
            CustomCheckList_res = customCheckList_res;
            Mediator = mediator;
        }
        public async Task<ApiResponse> CreateMaterialBase(InPut_BaseService7 inPut)//新料入库
        {
            try
            {
                PutInOrder putInOrder = await PutInOrder_res.FirstOrDefaultAsync(x => x.Consumer_MaterialId == inPut.Consumer_MaterialId && x.IsFinish == false);
                if (putInOrder == null)
                {
                    return new ApiResponse($"入库清单中未查询到{inPut.Consumer_MaterialId}", false, null);
                }
                MaterialBase materialBaseCheck = await MaterialBase_res.FirstOrDefaultAsync(x => x.Consumer_MaterialId == inPut.Consumer_MaterialId && x.BoxPosition != null);
                if (materialBaseCheck != null)
                {
                    return new ApiResponse($"料盒中已经存在{inPut.Consumer_MaterialId}", false, null);
                }
                BoxPosition boxPosition = await BoxPosition_res.FirstOrDefaultAsync(x => x.BoxPositionCode.Contains(inPut.BoxPositionCode) && x.MaterialBase == null);
                if (boxPosition == null)
                {
                    return new ApiResponse($"{inPut.BoxPositionCode}已无空位", false, null);
                }

                //create material
                MaterialBase materialBase = ObjectMapper.Map<PutInOrder, MaterialBase>(putInOrder);
                materialBase.CreatedDate = DateTime.Now;
                materialBase.PeoPle = User.UserName;
                materialBase.BoxPosition = boxPosition;
                materialBase.Id_BoxPosition = boxPosition.Id_BoxPosition;
                materialBase.MaterialuniqueCode = ExtendRandom.CreateRandom();
                materialBase.MaterialName = putInOrder.MaterialName;
                materialBase.Unit = putInOrder.Unit;
                materialBase.VirtualQuantity = materialBase.Quantity;
                await MaterialBase_res.InsertAsync(materialBase);
                //update putinorder
                putInOrder.State = "已入库";
                putInOrder.IsFinish = true;
                await PutInOrder_res.UpdateAsync(putInOrder);
                //mes通知

                loginHelper.LoginInfoAsync("sss", $"mes入库通知测试1{DateTime.Now}");
                List<Custom_InPut> custom_InPuts = new List<Custom_InPut>{new Custom_InPut
                  { BILLNO = putInOrder.Symbol,MATERIALCODE=putInOrder.MaterialCode,
                    BATCH=putInOrder.Batch,QTY=putInOrder.Quantity,
                    BARCODE=putInOrder.Consumer_MaterialId,PLANT="CN11"}};
                loginHelper.LoginInfoAsync("sss", $"mes入库通知测试2{DateTime.Now}");
                bool res = await toOutSideInterFace.RBTInRep(custom_InPuts);
                loginHelper.LoginInfoAsync("sss", $"mes入库通知测试3{DateTime.Now}");
                if (!res)
                {
                    loginHelper.LoginInfoAsync("sss", $"mes入库通知失败{putInOrder.Symbol}-{putInOrder.MaterialCode}-{putInOrder.Batch}-{putInOrder.Quantity}-{putInOrder.Consumer_MaterialId}");
                    return new ApiResponse("添加成功,通知入库mes失败", true, null);

                }
                //create log
                lognote lognote = new lognote()
                {
                    DateTime = DateTime.Now,
                    Type = "入库",
                    User = User.UserName,
                    Note = $"物料Id:{putInOrder.Consumer_MaterialId}+物料编号:{putInOrder.MaterialCode}+" +
                    $"箱号:{boxPosition.BoxPositionCode}+数量:{putInOrder.Quantity}"
                };
                await LogNote_res.InsertAsync(lognote);
                return new ApiResponse("加入料盒成功", true, null);

            }
            catch (Exception ex)
            {

                loginHelper.LoginAsync(inPut, "CreateMaterialBase");
                return new ApiResponse("ERROR-CreateMaterialBase", false, null);
            }

        }
        public async Task<ApiResponse> CreateLog(InPut_BaseService15 InPut)//添加日志
        {
            lognote lognote = new lognote();
            lognote.DateTime = DateTime.Now;
            lognote.User = InPut.User;
            lognote.Type = InPut.Type;
            lognote.Note = InPut.Note;
            await LogNote_res.InsertAsync(lognote);
            return new ApiResponse("添加成功", true, null);
        }
        public async Task<ApiResponse> Update_Box(InPut_BaseService2 input)//更改箱盒
        {
            try
            {
                //var boxs = await Box_res.WithDetailsAsync();
                //Box box=await  boxs.FirstOrDefaultAsync(x=>x.BoxCode == input.BoxCode);
                //if (box==null) return new ApiResponse("未查询到料盒", false, null);
                //foreach (var item in box.BoxGrids)
                //{
                //    if (item.materialBase!=null)
                //    {
                //        return new ApiResponse("料盒中有物料不允许修改", false, null);
                //    }
                //}
                //box.BoxCode = input.BoxCode;
                //box.BoxGrids.Clear();
                //await Box_res.UpdateAsync(box);
                //List<BoxGrid> boxGrids = new List<BoxGrid>();
                //for (int i = 0; i < input.BoxGridQuantity; i++)
                //{
                //    BoxGrid boxGrid = new BoxGrid();
                //    string BoxGridCode = $"{box.BoxCode}_{(i + 1).ToString("D2")}";
                //    boxGrid = boxGrid.AddBoxGrid(i+ 1, BoxGridCode, box, 0);
                //    boxGrids.Add(boxGrid);
                //}
                //await BoxGrid_res.InsertManyAsync(boxGrids);
                //box.BoxGrids.AddRange(boxGrids);
                //box.BoxGridQuantity = (int)input.BoxGridQuantity;
                //await Box_res.UpdateAsync(box);
                return new ApiResponse("更新成功", true, null);
                //var boxs = await Box_res.WithDetailsAsync();
                //foreach (var boxcode in input.BoxCode)
                //{
                //    Box box = boxs.FirstOrDefault(x => x.BoxCode == boxcode);
                //    if (box == null)
                //    {
                //        return new ApiResponse("未查询到", false, null);
                //    }                
                //    box.BoxGrids .Clear();
                //    await Box_res.UpdateAsync(box);
                //    await UnitOfWorkManager.Current.SaveChangesAsync();

                //    List<BoxGrid> boxGrids = new List<BoxGrid>();
                //    for (int i = 0; i < input.BoxGridQuantity; i++)
                //    {
                //        BoxGrid boxGrid = new BoxGrid();
                //        string BoxGridCode = $"{box.BoxCode}_{(i + 1).ToString("D2")}";
                //        boxGrid = boxGrid.AddBoxGrid(i + 1, BoxGridCode, box);              
                //        boxGrids.Add(boxGrid);

                //    }
                //    await BoxGrid_res.InsertManyAsync(boxGrids);
                //    box.BoxGrids.Clear();
                //    box.BoxGrids.AddRange(boxGrids);
                //    box.BoxGridQuantity = (int)input.BoxGridQuantity;
                //    await Box_res.UpdateAsync(box);

                //}
                //return new ApiResponse("更新成功", true, null);

            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(input, "Update_Box");
                return new ApiResponse("内部服务器错误", false, null);
            }


        }
        public async Task<ApiResponse> Update_WarehouseLines(InPut_BaseService5 inPut)//更新仓位状态
        {
            try
            {
                foreach (var item in inPut.WarehouseLineCodes)
                {
                    WarehouseLine warehouseLine = await WarehouseLine_res.FirstOrDefaultAsync(x => x.WarehouseLineCode == item);
                    if (warehouseLine != null)
                    {
                        warehouseLine.IsEnable = inPut.Type;
                    }
                    await WarehouseLine_res.UpdateAsync(warehouseLine);
                }
                return new ApiResponse("修改成功", true, null);

            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(inPut, "Update_WarehouseLines");
                return new ApiResponse("ERROR-Update_WarehouseLines", false, null);
            }



        }
        public async Task<ApiResponse> UpdateTaskOrderState(InPut_BaseService11 InPut)//修改任务状态
        {
            try
            {
                TaskOrder taskOrder = await TaskOrder_res.FirstOrDefaultAsync(x => x.TaskOrderCode == InPut.TaskOrderCode);
                if (taskOrder == null)
                {
                    return new ApiResponse("未查询到单号", false, null);
                }
                taskOrder.State = InPut.State;
                taskOrder.IsSend = InPut.IsSend;
                await TaskOrder_res.UpdateAsync(taskOrder);
                return new ApiResponse("修改成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, "UpdateTaskOrderState");
                return new ApiResponse("ERROR-UpdateTaskOrderState", false, null);
            }
        }
        public async Task<ApiResponse> GetList_InlethouesCode(string Type)
        {
            try
            {
                List<InlethouseLine> inlethouseLines = await Inlethouseline_res.GetListAsync(x => x.Type == Type);
                List<string> InlethouseCodes = inlethouseLines.Select(x => x.InlethouseLineCode).ToList();
                return new ApiResponse("获取成功", true, InlethouseCodes);
            }
            catch (Exception ex)
            {
                Logger.LogWarning($"GetList_InlethouesCode-{Type}");


                return new ApiResponse("ERROR-GetList_InlethouesCode", false, null);
            }
        }//获取出口   
        public async Task<ApiResponse> DeleteBox(InPut_BaseService8 InPut)//删箱子
        {
            try
            {
                //List<Box> BoxDel = new List<Box>();
                //if (string.IsNullOrEmpty(InPut.EndBoxCode))
                //{
                //    BoxDel.Add(await Box_res.FirstOrDefaultAsync(x => x.BoxCode == InPut.BoxCode));
                //}
                //else
                //{
                //    List<Box> boxes=  await Box_res.GetListAsync();
                //    BoxDel = boxes.Where(x => int.Parse(x.BoxCode.Substring(x.BoxCode.Length - 4)) >=
                //                            int.Parse(InPut.BoxCode.Substring(InPut.BoxCode.Length - 4)) &&
                //                            int.Parse(x.BoxCode.Substring(x.BoxCode.Length -4)) <=
                //                            int.Parse(InPut.EndBoxCode.Substring(InPut.EndBoxCode.Length - 4))).ToList();
                //}
                //bool res= BoxDel.Any(x => x.BoxGrids.Any(y => y.materialBase != null));
                //if (res)
                //{
                //    return new ApiResponse("有物料,无法删除", false, null);
                //}
                //await Box_res.DeleteManyAsync(BoxDel);
                return new ApiResponse("删除成功", true, null);
            }
            catch (Exception ex)
            {

                loginHelper.LoginAsync(InPut, "DeleteBox");
                return new ApiResponse("内部错误服务器", false, null);
            }

        }
        public async Task<ApiResponse> test()
        {
            try
            {
                lognote lognote = await context.lognotes.FirstOrDefaultAsync(x => x.Type == "测试故障");
                if (lognote != null)
                {
                    lognote.Note = "测试故障" + DateTime.Now;
                    await context.SaveChangesAsync();
                }

            }
            catch (SqlException ex)
            {
                loginHelper.LoginAsync(" ", $"Sq+测试故障" + ex.Message+DateTime.Now);
                return new ApiResponse("数据库连接异常请稍后再试", false, null);
            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(" ", $"Sq+测试故障" + ex.Message + DateTime.Now);
                return new ApiResponse("数据库连接异常请稍后再试", false, null);
            }


            return new ApiResponse("测试",true,"20258.22");
         

            //InPut_CunsumerService6 InPut = new InPut_CunsumerService6();
            //InPut.PlantCode="CN11";
            //InPut.OperateUser = User.UserName;
            //InPut.BusinessType = "快捷调整";
            //InPut.BarCode = query;
            //InPut.Remark = "调整备注";
            //InPut.Num = 6776;
            //var url = $"http://{GlobalVariable.CustomIp}/WMSWebApi/api/TASK/QuickAdjust";
            //var data = InPut;
            //string result = await url.PostJsonAsync(data).ReceiveString();
            //ApiResponseCustom2 Response = JsonConvert.DeserializeObject<ApiResponseCustom2>(result);
            //string var = JsonConvert.SerializeObject(Response);

            //return new ApiResponse("成功", Response.IsSuccess, var);

        }
        public async Task<ApiResponse> RemovesMaterial(List<string> MaterialCodes)//删料
        {
            try
            {
                List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x => MaterialCodes.Any(y => y == x.MaterialCode));
                materialBases.ForEach(x => x.Id_BoxPosition = null);
                await MaterialBase_res.DeleteManyAsync(materialBases);
                return new ApiResponse("删除成功", true, null);
            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(MaterialCodes, "RemovesMaterial");

                return new ApiResponse("ERROR-RemovesMaterial", false, null);
            }

        }
        public async Task<ApiResponse> UpdateMaterialBaserQuantity(InPut_BaseService7 inPut)//更新物料数量
        {
            try
            {
                //var MaterialBases = await MaterialBase_res.WithDetailsAsync();
                //MaterialBase materialBaseJudge = await MaterialBases.FirstOrDefaultAsync(x => x.MaterialProperty.MaterialProertyname == inPut.MaterialProertyName && x.BoxGrid.TheBox.BoxCode== inPut.BoxCode);
                //if (materialBaseJudge == null) return new ApiResponse("未查询到物料", false, null);
                //#region  operate
                ////update materialbase 
                //materialBaseJudge.Quantity = materialBaseJudge.Quantity+ inPut.Quantity;
                //await MaterialBase_res.UpdateAsync(materialBaseJudge);
                return new ApiResponse("更新成功", true, null);

            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(inPut, "UpdateMaterialBaserQuantity");
                return new ApiResponse("ERROR-UpdateMaterialBaserQuantity", false, null);
            }
        }
        public async Task<ApiResponse> CreateMaterialProperty(InPut_BaseService14 InPut)//添加物料属性
        {
            try
            {
                MaterialProperty materialProperty = new MaterialProperty();
                materialProperty.MaterialProertyname = InPut.MaterialProertyname;
                materialProperty.Description = InPut.Description;
                materialProperty.Unit = InPut.Unit;
                materialProperty.Type = InPut.Type;
                await MaterialProperty_res.InsertAsync(materialProperty);
                return new ApiResponse("添加成功", true, null);
            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "CreateMaterialProperty");
                return new ApiResponse("ERROR-CreateMaterialProperty", false, null);
            }
        }
        //使用中
        public async Task<ApiResponse> Create_Inlethouse(InPut_BaseService9 input)
        {
            try
            {

                bool result = await Inlethouseline_res.AnyAsync(x => x.Xaxis == input.Xaxis && x.Yaxis == input.Yaxis && x.Zaxis == input.Zaxis && x.Type == input.Type);
                if (result) return new ApiResponse("入出.库口已存在", false, null);
                Inlethouse inlethouse = new Inlethouse();
                inlethouse = inlethouse.AddInlethouse(input.InlethouseCode, input.Xaxis, input.Yaxis, input.Zaxis, input.InlethouseName, input.parameter);
                InlethouseLine inlethouseLine = new InlethouseLine();
                inlethouseLine = inlethouseLine.AddInlethouseline(input.Long, input.Wide, input.high, input.Xaxis, input.Yaxis, input.Zaxis, null, input.Type, input.LineType);
                inlethouseLine.InlethouseLineCode = input.InlethouseCode;
                inlethouseLine.TheInlethouse = inlethouse;
                inlethouse.inlethouselines.Add(inlethouseLine);
                await Inlethouse_res.InsertAsync(inlethouse);
                await Inlethouseline_res.InsertAsync(inlethouseLine);
                return new ApiResponse("配置成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(input, "Create_Inlethouse");
                return new ApiResponse("ERROR-Create_Inlethouse", false, null);
            }

        }//配置入库口
        public async Task<ApiResponse> Create_Warehouses(InPut_BaseService3 input)//配置库位
        {
            try
            {
                bool res = await Warehouse_res.AnyAsync(x => x.WarehouseName == input.WarehouseName);
                if (res)
                {
                    return new ApiResponse("库位名称重复", false, null);
                }
                BoxType binType = await BinType_res.FirstOrDefaultAsync(x => x.BoxType_Name == input.BinType_Name);
                if (binType == null)
                {
                    return new ApiResponse("查询不到的Bintype", false, null);
                }
                Warehouse warehouse = new Warehouse();
                warehouse = warehouse.AddWarehouse(input.WarehouseCode, input.Xaxis, input.Yaxis, input.Zaxis, input.WarehouseName, input.parameter, input.Type);
                await Warehouse_res.InsertAsync(warehouse);
                int sum = input.Xaxis * input.Yaxis * input.Zaxis;
                List<WarehouseLine> lines = new List<WarehouseLine>();
                //排
                for (int j = 1; j <= input.Xaxis; j++)
                {
                    //高
                    for (int k = 1; k <= input.Yaxis; k++)
                    {
                        //列
                        for (int y = 1; y <= input.Zaxis; y++)
                        {
                            if (!input.Double)
                            {
                                WarehouseLine warehouseLine = new WarehouseLine();
                                warehouseLine = warehouseLine.AddWarehouseline(binType.Width, binType.Height, binType.DePth, j, k, y, warehouse, binType);
                                warehouseLine.WarehouseLineCode = warehouse.WarehouseCode + "-" + j.ToString("D3") + "-" + k.ToString("D3") + "-" + y.ToString("D2");
                                lines.Add(warehouseLine);
                            }
                            else
                            {
                                WarehouseLine warehouseLine = new WarehouseLine();
                                warehouseLine = warehouseLine.AddWarehouseline(binType.Width, binType.Height, binType.DePth, j, k, y, warehouse, binType);
                                warehouseLine.WarehouseLineCode = warehouse.WarehouseCode + "-" + j.ToString("D3") + "-" + k.ToString("D3") + "-" + y.ToString("D2") + "_1";
                                lines.Add(warehouseLine);
                                WarehouseLine warehouseLine2 = new WarehouseLine();
                                warehouseLine2 = warehouseLine2.AddWarehouseline(binType.Width, binType.Height, binType.DePth, j, k, y, warehouse, binType);
                                warehouseLine2.WarehouseLineCode = warehouse.WarehouseCode + "-" + j.ToString("D3") + "-" + k.ToString("D3") + "-" + y.ToString("D2") + "_2";
                                lines.Add(warehouseLine2);
                            }
                        }
                    }
                }
                warehouse.warehouselines.AddRange(lines);
                await Warehouse_res.InsertAsync(warehouse);
                await WarehouseLine_res.InsertManyAsync(lines);
                return new ApiResponse("配置成功", true, null);
            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(input, "Create_Warehouses");
                return new ApiResponse("ERROR-Create_Warehouses", false, null);
            }

        }
        public async Task<ApiResponse> Create_Inlethouses(InPut_BaseService9 input)//配置缓存货位
        {
            try
            {
                bool res = await Inlethouse_res.AnyAsync(x => x.InlethouseName == input.InlethouseName);
                if (res)
                {
                    return new ApiResponse("库位名称重复", false, null);
                }
                Inlethouse inlethouse = new Inlethouse();
                inlethouse = inlethouse.AddInlethouse(input.InlethouseCode, input.Xaxis, input.Yaxis, input.Zaxis, input.InlethouseName, input.parameter);
                await Inlethouse_res.InsertAsync(inlethouse);
                int sum = input.Xaxis * input.Yaxis * input.Zaxis;
                List<InlethouseLine> lines = new List<InlethouseLine>();
                //排
                for (int j = 1; j <= input.Xaxis; j++)
                {
                    //高
                    for (int k = 1; k <= input.Yaxis; k++)
                    {
                        //列
                        for (int y = 1; y <= input.Zaxis; y++)
                        {
                            InlethouseLine inlethouseLine = new InlethouseLine();
                            inlethouseLine = inlethouseLine.AddInlethouseline(input.Long, input.Wide, input.high, j, k, y, inlethouse, input.Type, null);
                            inlethouseLine.InlethouseLineCode = inlethouse.InlethouseCode + "-" + j.ToString("D2") + "-" + k.ToString("D2") + "-" + y.ToString("D2");
                            lines.Add(inlethouseLine);
                        }
                    }
                }
                inlethouse.inlethouselines.AddRange(lines);
                await Inlethouse_res.InsertAsync(inlethouse);
                await Inlethouseline_res.InsertManyAsync(lines);
                return new ApiResponse("配置成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(input, "Create_Inlethouses");
                return new ApiResponse("ERROR-Create_Inlethouses", false, null);
            }
        }
        public async Task<ApiResponse> Create_Boxs(InPut_BaseService input)//配置箱盒
        {
            try
            {

                bool res = await Box_res.AnyAsync(x => x.BoxCode.Substring(x.BoxCode.Length - 4) == input.StartNumber.ToString("D4") ||
                                                  x.BoxCode.Substring(x.BoxCode.Length - 4) == input.EndNumber.ToString("D4"));
                if (res)
                {
                    return new ApiResponse("箱盒已存在", false, null);
                }
                BoxType binType = await BinType_res.FirstOrDefaultAsync(x => x.BoxType_Name == input.BinType_Name);
                if (binType == null)
                {
                    return new ApiResponse("查询不到的Bintype", false, null);
                }
                //配置箱盒
                int boxquantity = input.EndNumber - input.StartNumber + 1;
                List<Box> boxes = new List<Box>();
                for (int i = 0; i < boxquantity; i++)//箱
                {
                    Box box = new Box();
                    string BoxCode = input.Name + "00000" + (input.StartNumber + i).ToString("D4");
                    box = box.AddBox(BoxCode, input.BoxGridQuantity, input.VirtualSpace, binType);
                    List<BoxGrid> boxGrids = new List<BoxGrid>();
                    for (int y = 0; y < input.BoxGridQuantity; y++)//格
                    {
                        //有虚拟货位
                        if (input.VirtualSpace)
                        {
                            BoxGrid boxGrid = new BoxGrid();
                            string BoxGridCode = $"{BoxCode}-{(y + 1)}";
                            boxGrid = boxGrid.AddBoxGrid(y + 1, BoxGridCode, box, input.PostionQuantity);
                            boxGrids.Add(boxGrid);
                            List<BoxPosition> boxPositions = new List<BoxPosition>();
                            for (int x = 1; x <= input.PostionQuantity; x++)
                            {
                                BoxPosition boxPosition = new BoxPosition();
                                string BoxPositionCode = $"{BoxGridCode}-{x}";
                                boxPosition = boxPosition.AddBoxPosition(BoxPositionCode, boxGrid, x);
                                boxPositions.Add(boxPosition);
                            }
                            await BoxPosition_res.InsertManyAsync(boxPositions);
                        }
                        //无虚拟货位
                        else
                        {
                            BoxGrid boxGrid = new BoxGrid();
                            string BoxGridCode = $"{BoxCode}-{(y + 1)}";
                            boxGrid = boxGrid.AddBoxGrid(y + 1, BoxGridCode, box, 0);
                            boxGrids.Add(boxGrid);
                        }

                    }
                    await BoxGrid_res.InsertManyAsync(boxGrids);
                    box.BoxGrids.AddRange(boxGrids);
                    boxes.Add(box);
                }
                await Box_res.InsertManyAsync(boxes);
                return new ApiResponse("生成成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(input, "Create_Boxs");
                return new ApiResponse("ERROR-Create_Boxs", false, null);
            }
        }
        public async Task<ApiResponse> CreateTaskOrder(InPut_BaseService6 InPut)//添加agv入库任务
        {
            try
            {
                Box box = await context.boxs.Include(x => x.WarehouseLine).Include(x => x.BinType).Include(x => x.BoxGrids).
                            ThenInclude(x => x.BoxPositions).ThenInclude(x => x.MaterialBase).ThenInclude(x => x.NeetOutMaterials).
                            FirstOrDefaultAsync(x => x.BoxCode == InPut.BoxCode);
                if (box == null)
                {
                    return new ApiResponse("未查询到料盒", false, null);
                }
                string EssWarehouline = await toOutSideInterFace.queryContainer(box.BoxCode);
                if (EssWarehouline.Contains("HAI"))
                {
                    return new ApiResponse("ESS检查料盒已上架,请核对库位", false, null);
                }

                List<NeetOutMaterial> allNeetOutMaterials = box?.BoxGrids?
   .SelectMany(grid => grid.BoxPositions.SelectMany(position => position.MaterialBase?.NeetOutMaterials ?? Enumerable.Empty<NeetOutMaterial>()))
   .ToList();

                //移动输送线
                if (allNeetOutMaterials.Count > 0)
                {

                    if (allNeetOutMaterials.Any(x => x.Machine == InPut.Machine))
                    {
                        return new ApiResponse("该箱盒有正在出库的物料,请出完", false, null);
                    }
                    if (allNeetOutMaterials.Any(x => x.Machine != InPut.Machine))
                    {
                        InPut_EssService5 Ess_InPut5 = new InPut_EssService5();
                        if (InPut.Machine == 1)
                        {
                            Ess_InPut5.TaskType = "移位-2";
                            Ess_InPut5.SlotCode = "1-4";
                            Ess_InPut5.BoxCode = box.BoxCode;
                            Ess_InPut5.Direction = "2";
                        }
                        else
                        {
                            Ess_InPut5.TaskType = "移位-1";
                            Ess_InPut5.SlotCode = "1-5";
                            Ess_InPut5.BoxCode = box.BoxCode;
                            Ess_InPut5.Direction = "1";
                        }
                        bool res2 = await toOutSideInterFace.moveContainer(Ess_InPut5.BoxCode, Ess_InPut5.Direction, Ess_InPut5.SlotCode);
                        if (res2)
                        {
                            MoveContainerInfo moveContainerInfo = new MoveContainerInfo();
                            moveContainerInfo.TaskType = Ess_InPut5.TaskType;
                            moveContainerInfo.BoxCode = Ess_InPut5.BoxCode;
                            await MoveContainerInfo_res.InsertAsync(moveContainerInfo);
                        }
                        lognote lognote = new lognote() { DateTime = DateTime.Now, BoxCode = InPut.BoxCode, Type = "输送线流动", Note = Ess_InPut5.SlotCode + Ess_InPut5.Direction };
                        await LogNote_res.InsertAsync(lognote);
                        return new ApiResponse($"该箱盒有正在出库的物料,移动至{Ess_InPut5.Direction}", true, null);
                    }
                }

                //create taskorder
                if (box == null)
                {
                    return new ApiResponse("未查询到箱盒", false, null);
                }
                if (box.WarehouseLine != null)
                {
                    return new ApiResponse("箱盒已在货架上", false, null);
                }
                List<WarehouseLine> warehouseLines = await WarehouseLine_res.GetListAsync(x => x.Box == null && x.IsEnable == true && x.BinType == box.BinType && x.IsOccupy == false && x.Box == null);
                if (warehouseLines.Count == 0)
                {
                    return new ApiResponse("库位已用完", false, null);
                }
                WarehouseLine warehouseLine = warehouseLines.OrderBy(x => Random.Shared.Next()).First();
                var inlethouseLines = await Inlethouseline_res.WithDetailsAsync();
                InlethouseLine inlethouseLine = await inlethouseLines.FirstOrDefaultAsync(x => x.IsEnable == true && x.InlethouseLineCode.Contains(InPut.InletCode));
                if (inlethouseLine == null)
                {
                    return new ApiResponse("缓存货架已用完/查询不到", false, null);
                }
                bool res = await TaskOrder_res.AnyAsync(x => x.Id_Box == box.Id_Box);
                if (res) return new ApiResponse("已存在相同箱盒任务/或者任务还没结束,请检查ESS系统", false, null);
                TaskOrder taskOrder = new TaskOrder();
                taskOrder.Box = box;
                taskOrder.Type = "入库";
                taskOrder.WarehouseCode = warehouseLine.WarehouseLineCode;
                taskOrder.InlethouseCode = inlethouseLine.InlethouseLineCode;
                taskOrder.CreatTime = DateTime.Now;
                taskOrder.State = "未下发";
                taskOrder.Machine = InPut.Machine;
                taskOrder.TaskOrderCode = ExtendRandom.CreateRandom();
                box.TaskOrder = taskOrder;
                await Box_res.UpdateAsync(box);
                await TaskOrder_res.InsertAsync(taskOrder);
                warehouseLine.IsOccupy = true;
                await WarehouseLine_res.UpdateAsync(warehouseLine);
                inlethouseLine.IsOccupy = true;
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                return new ApiResponse("任务生成成功", true, inlethouseLine.InlethouseLineCode);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, "CreateTaskOrder");
                return new ApiResponse("ERROR-CreateTaskOrder", false, null);
            }

        }
        public async Task<ApiResponse> DeleteTaskOrder(List<string> TaskOrderCodes)
        {
            try
            {
                List<TaskOrder> taskOrders = await TaskOrder_res.GetListAsync(x => TaskOrderCodes.Any(y => y == x.TaskOrderCode));
                List<string> warehouseLinecode = taskOrders.Select(x => x.WarehouseCode).ToList();
                List<WarehouseLine> warehouseLines = await WarehouseLine_res.GetListAsync(x => warehouseLinecode.Any(y => y == x.WarehouseLineCode));
                warehouseLines = warehouseLines.Where(x => taskOrders.Any(y => y.WarehouseCode == x.WarehouseLineCode)).ToList();
                List<InlethouseLine> inlethouseLines = await Inlethouseline_res.GetListAsync();
                inlethouseLines = inlethouseLines.Where(x => taskOrders.Any(y => y.InlethouseCode == x.InlethouseLineCode)).ToList();
                //List<Box> boxs = await context.boxs.Include(x => x.BoxGrids).ThenInclude(x => x.BoxPositions).ThenInclude(x => x.MaterialBase).ToListAsync();
                //boxs = boxs.Where(x => taskOrders.Any(y => y.Id_Box == x.Id_Box)).ToList();
                bool res = taskOrders.Any(x => x.State != "未下发");
                if (res) { return new ApiResponse("只能删除未下发的任务", false, null); }

                if (taskOrders.All(x => x.Type == "入库"))
                {
                    warehouseLines.ForEach(x => x.IsOccupy = false);
                    await WarehouseLine_res.UpdateManyAsync(warehouseLines);
                }
                inlethouseLines.ForEach(x =>
                {
                    x.IsOccupy = false;
                    x.Box = null;
                });
                //boxs.ForEach(x =>
                //{
                //    x.InlethouseLine = null;
                //    foreach (var boxGrid in x.BoxGrids)
                //    {
                //        foreach (var boxPosition in boxGrid.BoxPositions)
                //        {
                //            if (boxPosition.MaterialBase != null)
                //            {
                //                boxPosition.MaterialBase.Islock = false;
                //            }

                //        }
                //    }
                //});
                await Inlethouseline_res.UpdateManyAsync(inlethouseLines);
                //await Box_res.UpdateManyAsync(boxs);
                await TaskOrder_res.DeleteManyAsync(taskOrders);
                Logger.LogInformation($"DeleteTaskOrder{TaskOrderCodes}");

                lognote lognote = new lognote()
                {
                    DateTime = DateTime.Now,
                    User = "删除任务",
                    Type = "删除了task任务",
                    Note = taskOrders.ToString()
                };
                await context.AddAsync(lognote);
                return new ApiResponse("已删除任务", true, null);
            }
            catch (Exception ex)
            {

                Logger.LogError($"DeleteTaskOrder{TaskOrderCodes}" + ex);
                return new ApiResponse("ERROR-DeleteTaskOrder", false, null);
            }

        }//删除任务      
        public async Task<ApiResponse> CreateTaskOrderOut(InPut_BaseService13 InPut)//agv出库任务
        {
            try
            {
                List<TaskOrder> taskOrders = await TaskOrder_res.WithDetails().ToListAsync();
                List<TaskOrder> taskOrdersDel = taskOrders.Where(x => InPut.BoxCodes.Any(y => y == x.Box.BoxCode)).ToList();
                //List<Box> boxes = await Box_res.WithDetails().ToListAsync();
                //boxes = boxes.Where(x => InPut.BoxCodes.Any(y => y == x.BoxCode)).ToList();
                var boxequery = context.boxs.Include(x => x.WarehouseLine).Where(x => InPut.BoxCodes.Any(y => y == x.BoxCode));
                List<Box> boxes = await boxequery.ToListAsync();
                boxes = boxes.Where(x => !taskOrdersDel.Any(y => y.Id_Box == x.Id_Box)).ToList();
                bool res = boxes.Any(x => x.WarehouseLine == null);
                if (res)
                {
                    return new ApiResponse("有料盒不在货架上", false, null);
                }
                if (InPut.BoxCodes.Count > 12)
                {
                    return new ApiResponse("一次最多下方12个任务", false, null);
                }
                InlethouseLine inlethouseLine = await Inlethouseline_res.FirstOrDefaultAsync(x => x.InlethouseLineCode.Contains(InPut.InlethouseCode));
                if (inlethouseLine == null)
                {
                    return new ApiResponse("查询不到的出库口", false, null);
                }
                List<TaskOrder> taskOrdersInsert = new List<TaskOrder>();
                inlethouseLine.IsOccupy = true;
                int i = 0;
                foreach (var item in boxes)
                {
                    TaskOrder taskOrder = new TaskOrder();
                    taskOrder = taskOrder.AddTaskOrder("出库", item.Id_Box, item.WarehouseLine.WarehouseLineCode, inlethouseLine.InlethouseLineCode,
                                                        "手动", 1, 1, InPut.Machine);
                    taskOrdersInsert.Add(taskOrder);
                    item.Machine = InPut.Machine.ToString();
                    i++;
                }
                await TaskOrder_res.InsertManyAsync(taskOrdersInsert);
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                await Box_res.UpdateManyAsync(boxes);
                return new ApiResponse("任务生成成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, "CreateTaskOrderOut");
                return new ApiResponse("ERROR-CreateTaskOrderOut", false, null);
            }
        }
        public async Task<ApiResponse> Create_Bintype(InPut_BaseService16 InPut)//配置bin
        {
            try
            {
                bool binTypeCheck = await BinType_res.AnyAsync(x => x.BoxType_Name == InPut.BinType_Name);
                if (binTypeCheck)
                {
                    return new ApiResponse("BinName重复", false, null);
                }
                BoxType binType = new BoxType();
                binType.BoxType_Name = InPut.BinType_Name;
                binType.DePth = InPut.DePth;
                binType.Width = InPut.Width;
                binType.Height = InPut.Height;
                await BinType_res.InsertAsync(binType);
                return new ApiResponse("添加Bintype成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, "Create_Bintype");
                return new ApiResponse("ERROR-Create_Bintype", false, null);
            }

        }
        public async Task<ApiResponse> Getlist_Bintypes()//获取bins
        {
            List<BoxType> binTypes = await BinType_res.GetListAsync();
            return new ApiResponse("添加Bintype成功", true, binTypes);
        }
        public async Task<ApiResponse> CreateNeetOutMaterial(InPut_BaseService10 InPut)//手动出库-添加需出料-添加agv任务-输送线0
        {
            try
            {
                //List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x =>InPut. MaterialCodes.Any(y => y == x.MaterialCode));
                List<MaterialBase> materialBases = MaterialBase_res.WithDetails().ToList();
                List<NeetOutMaterial> NeetOutMaterials = await NeetOutMaterial_res.GetListAsync(x => InPut.MaterialuniqueCodes.Any(y => y == x.Material.MaterialuniqueCode));
                List<string> MaterialuniqueCodesDel = NeetOutMaterials.Select(x => x.Material.MaterialuniqueCode).ToList();
                InPut.MaterialuniqueCodes = InPut.MaterialuniqueCodes.Except(MaterialuniqueCodesDel).ToList();
                materialBases = materialBases.Where(x => InPut.MaterialuniqueCodes.Any(y => y == x.MaterialuniqueCode)).ToList();
                //var taskOrders = await TaskOrder_res.GetListAsync(x => materialBases.Any(y => y.Info== x.Box.BoxCode));
                List<TaskOrder> taskOrders = await TaskOrder_res.WithDetails().ToListAsync();
                taskOrders = taskOrders.Where(x => materialBases.Any(y => y.BoxPosition.TheBoxGrid.TheBox.BoxCode == x.Box.BoxCode && x.Type == "出库")).ToList();
                List<TaskOrder> taskOrderLussed = taskOrders.Where(x => x.State == "已下发").ToList();
                if (taskOrderLussed.Count > 0)
                {
                    return new ApiResponse(taskOrders[0].Box.BoxCode + "已发送AGV任务,无法再次添加出库", false, null);
                }
                bool RES = materialBases.Any(X => X.Islock == true);
                if (RES)
                {
                    return new ApiResponse("已经锁定的物料无法再次被选中", false, null);
                }
                List<MaterialBase> materialBasesTask = materialBases.DistinctBy(x => x.BoxPosition.TheBoxGrid.TheBox.BoxCode).ToList();
                InlethouseLine inlethouseLine = await Inlethouseline_res.FirstOrDefaultAsync(x => x.InlethouseLineCode == InPut.InlethouseCode);
                if (inlethouseLine == null)
                {
                    return new ApiResponse(InPut.InlethouseCode + "未查询到的出库口", false, null);
                }
                #region operate
                //creater neetOutMaterial
                List<NeetOutMaterial> neetOutMaterials = new List<NeetOutMaterial>();

                foreach (var materialBase in materialBases)
                {
                    NeetOutMaterial neetOutMaterial = new NeetOutMaterial();
                    neetOutMaterial = neetOutMaterial.AddNeetOutMaterial(materialBase, "手动出库", int.TryParse(materialBase.Poundage, out var poundage) && poundage > 0 ? poundage : materialBase.Quantity, null, null, null, InPut.Machine);
                    neetOutMaterials.Add(neetOutMaterial);
                    materialBase.Islock = false;
                    materialBase.NeetOutMaterials.Add(neetOutMaterial);
                }
                ////creater taskorder


                List<TaskOrder> taskOrderNotfinsih = taskOrders.ToList();
                materialBasesTask = materialBasesTask.Where(x => !taskOrderNotfinsih.Any(y => y.Box.BoxCode == x.BoxPosition.TheBoxGrid.TheBox.BoxCode)).ToList();//去掉已在任务中有的箱盒
                int i = 0;
                List<TaskOrder> taskorderDto = new List<TaskOrder>();
                foreach (var item in materialBasesTask)
                {
                    TaskOrder taskOrder = new TaskOrder();
                    taskOrder = taskOrder.AddTaskOrder("出库", item.BoxPosition.TheBoxGrid.TheBox.Id_Box,
                        item.BoxPosition.TheBoxGrid.TheBox.WarehouseLine.WarehouseLineCode, inlethouseLine.InlethouseLineCode, "手动", 0, 0, InPut.Machine);
                    item.BoxPosition.TheBoxGrid.TheBox.TaskOrder = taskOrder;
                    item.BoxPosition.TheBoxGrid.TheBox.Machine = InPut.Machine.ToString();
                    inlethouseLine.IsOccupy = true;
                    await Box_res.UpdateAsync(item.BoxPosition.TheBoxGrid.TheBox);
                    taskorderDto.Add(taskOrder);
                    i++;
                }
                //已经加入任务的箱子的需要出的物料添加任务外键




                List<TaskOrderDto> Dto = ObjectMapper.Map<List<TaskOrder>, List<TaskOrderDto>>(taskorderDto);
                await NeetOutMaterial_res.InsertManyAsync(neetOutMaterials);
                await TaskOrder_res.InsertManyAsync(taskorderDto);
                await MaterialBase_res.UpdateManyAsync(materialBases);
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                return new ApiResponse("已添加至需出料", true, Dto);
                #endregion
            }

            catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "CreateNeetOutMaterial");
                return new ApiResponse("ERROR-CreateNeetOutMaterial", false, null);
            }
        }
        //手动出库-添加需出料-添加agv任务-缓存货架
        //try
        //{
        //    //List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x =>InPut. MaterialCodes.Any(y => y == x.MaterialCode));
        //    List<MaterialBase> materialBases = MaterialBase_res.WithDetails().ToList();
        //    List<NeetOutMaterial> NeetOutMaterials = await NeetOutMaterial_res.GetListAsync(x => InPut.MaterialuniqueCodes.Any(y => y == x.Material.MaterialuniqueCode));
        //    List<string> MaterialuniqueCodesDel = NeetOutMaterials.Select(x => x.Material.MaterialuniqueCode).ToList();
        //    InPut.MaterialuniqueCodes = InPut.MaterialuniqueCodes.Except(MaterialuniqueCodesDel).ToList();
        //    materialBases = materialBases.Where(x => InPut.MaterialuniqueCodes.Any(y => y == x.MaterialuniqueCode)).ToList();
        //    //var taskOrders = await TaskOrder_res.GetListAsync(x => materialBases.Any(y => y.Info== x.Box.BoxCode));
        //    List<TaskOrder> taskOrders = await TaskOrder_res.WithDetails().ToListAsync();
        //    taskOrders = taskOrders.Where(x => materialBases.Any(y => y.BoxPosition.TheBoxGrid.TheBox.BoxCode == x.Box.BoxCode && x.Type == "出库")).ToList();
        //    List<TaskOrder> taskOrderLussed = taskOrders.Where(x => x.State == "已下发").ToList();
        //    if (taskOrderLussed.Count > 0)
        //    {
        //        return new ApiResponse(taskOrders[0].Box.BoxCode + "已发送AGV任务,无法再次添加出库", false, null);
        //    }
        //    List<MaterialBase> materialBasesTask = materialBases.DistinctBy(x => x.BoxPosition.TheBoxGrid.TheBox.BoxCode).ToList();
        //    List<InlethouseLine> inlethouseLine\ = await Inlethouseline_res.GetListAsync(x => x.IsOccupy == false && x.Box == null && x.InlethouseLineCode.Contains(InPut.InlethouseCode));
        //    if (materialBasesTask.Count > inlethouseLine\.Count)
        //    {
        //        return new ApiResponse("当前可用缓存不够,请减少任务", false, null);
        //    }

        //    #region operate
        //    //creater neetOutMaterial
        //    List<NeetOutMaterial> neetOutMaterials = new List<NeetOutMaterial>();

        //    foreach (var materialBase in materialBases)
        //    {
        //        NeetOutMaterial neetOutMaterial = new NeetOutMaterial();
        //        neetOutMaterial = neetOutMaterial.AddNeetOutMaterial(materialBase, "手动出库", materialBase.Quantity, null, null, null);

        //        neetOutMaterials.Add(neetOutMaterial);

        //        materialBase.NeetOutMaterials.Add(neetOutMaterial);
        //    }
        //    await NeetOutMaterial_res.InsertManyAsync(neetOutMaterials);
        //    ////creater taskorder


        //    List<TaskOrder> taskOrderNotfinsih = taskOrders.ToList();
        //    materialBasesTask = materialBasesTask.Where(x => !taskOrderNotfinsih.Any(y => y.Box.BoxCode == x.BoxPosition.TheBoxGrid.TheBox.BoxCode)).ToList();//去掉已在任务中有的箱盒
        //    int i = 0;
        //    List<TaskOrder> taskorders = new List<TaskOrder>();
        //    foreach (var item in materialBasesTask)
        //    {
        //        TaskOrder taskOrder = new TaskOrder();
        //        taskOrder = taskOrder.AddTaskOrder("出库", item.BoxPosition.TheBoxGrid.TheBox, item.BoxPosition.TheBoxGrid.TheBox.WarehouseLine.WarehouseLineCode, inlethouseLine\[i].InlethouseLineCode, "手动出库", null, null);
        //        item.BoxPosition.TheBoxGrid.TheBox.TaskOrder = taskOrder;
        //        inlethouseLine\[i].IsOccupy = true;
        //        foreach (var neetOutMaterial in neetOutMaterials)
        //        {
        //            if (neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox.Id_Box == taskOrder.Box.Id_Box)
        //            {
        //                neetOutMaterial.TheTaskOrder = taskOrder;
        //            }
        //        }

        //        await Box_res.UpdateAsync(item.BoxPosition.TheBoxGrid.TheBox);
        //        taskorders.Add(taskOrder);
        //        i++;
        //    }
        //    List<TaskOrderDto> Dto = ObjectMapper.Map<List<TaskOrder>, List<TaskOrderDto>>(taskorders);
        //    await NeetOutMaterial_res.InsertManyAsync(neetOutMaterials);
        //    await TaskOrder_res.InsertManyAsync(taskOrders);
        //    await MaterialBase_res.UpdateManyAsync(materialBases);
        //    await Inlethouseline_res.UpdateManyAsync(inlethouseLine\);
        //    return new ApiResponse("已添加至需出料", true, Dto);
        //    #endregion
        //}

        //catch (Exception ex)
        //{
        //    loginHelper.LoginAsync(InPut, "CreateNeetOutMaterial");
        //    return new ApiResponse("CreateNeetOutMaterial-ERROR", false, null);
        //}
        public async Task<ApiResponse> DeleteMaterial(InPut_BaseService4 input)//取料确认
        {
            try
            {
                View_NeetOutMaterial view_NeetOutMaterial = await context.View_NeetOutMaterials.
                    FirstOrDefaultAsync(x => x.BoxPositionCode.Contains(input.BoxPositionCode)
                && x.Consumer_MaterialId == input.Consumer_MaterialId && x.Machine == input.Machine);
                if (view_NeetOutMaterial == null)
                {
                    return new ApiResponse("未查询到需出料", false, null);
                }
                if (view_NeetOutMaterial.Machine != input.Machine)
                {
                    return new ApiResponse("请勿在此操作台拾取该料", false, null);
                }
                var materialBases = await MaterialBase_res.WithDetailsAsync();
                MaterialBase materialBase = await materialBases.FirstOrDefaultAsync(x => x.MaterialuniqueCode == view_NeetOutMaterial.MaterialuniqueCode);
                if (materialBase == null)
                {
                    return new ApiResponse($"未查询到实物{view_NeetOutMaterial.Consumer_MaterialId}", false, null);
                }
                if (materialBase.BoxPosition.TheBoxGrid.TheBox.WarehouseLine != null)
                {
                    return new ApiResponse($"检查到{materialBase.BoxPosition.TheBoxGrid.TheBox.BoxCode}未下架", false, null);
                }
                //播种墙 check
                bool res = await SowingWallLine_res.AnyAsync(x => x.IsLight == true && x.Mchine == input.Machine.ToString());
                if (res)
                {
                    return new ApiResponse("检测到有灯未灭", false, null);
                }
                SowingWallLine sowingWallLine = await SowingWallLine_res.FirstOrDefaultAsync(x => x.Info == view_NeetOutMaterial.OrderNo);
                if (sowingWallLine == null)
                {
                    sowingWallLine = await SowingWallLine_res.FirstOrDefaultAsync(x => x.Info == null && x.Mchine == input.Machine.ToString());
                }
                if (sowingWallLine == null)
                {
                    return new ApiResponse("没有可用的播种墙", false, null);
                }
                //update sowingwallinfo 亮灯       
                bool res2 = await toOutSideInterFace.sendCommand("RED", sowingWallLine.SowingWallLine_Name, view_NeetOutMaterial.NeetQuantity.ToString());
                if (!res2)
                {
                    return new ApiResponse("亮灯失败,出库失败", false, null);
                }
                sowingWallLine.Info = view_NeetOutMaterial.OrderNo.ToString();
                sowingWallLine.IsLight = false;
                sowingWallLine.IsOccupy = true;
                await SowingWallLine_res.UpdateAsync(sowingWallLine);
                //update neetoutmaterial
                NeetOutMaterial neetOutMaterial = await context.neetOutMaterials.FirstOrDefaultAsync(x => x.Id_NeetOutMaterial == view_NeetOutMaterial.Id_NeetOutMaterial);
                //check orderbatch
                bool OrderBatchCheck = true;
                if (neetOutMaterial != null && !string.IsNullOrEmpty(neetOutMaterial.OrderBatch))
                {
                    var orderbatchlist = await context.neetOutMaterials.Where(x => x.OrderBatch == neetOutMaterial.OrderBatch).ToListAsync();
                    if (orderbatchlist.Count == 1)
                    {
                        OrderBatchCheck = false;
                    }

                }
                string OrderBatch = neetOutMaterial.OrderBatch;
                //delete neetoutmaterial
                await NeetOutMaterial_res.DeleteAsync(neetOutMaterial);
                //await UnitOfWorkManager.Current.SaveChangesAsync();
                //update materialbase
                materialBase.Quantity = (int)(materialBase.Quantity - view_NeetOutMaterial.NeetQuantity);
                materialBase.PeoPle = User.UserName;
                materialBase.UpdateTime = DateTime.Now;
                await MaterialBase_res.UpdateAsync(materialBase);
               
                //CREATE  LOG
                lognote lognote = new lognote();
                lognote.DateTime = DateTime.Now;
                lognote.User = User.UserName;
                lognote.Type = "出库";
                lognote.Note = $"物料Id:{view_NeetOutMaterial.Consumer_MaterialId}-物料编号:{view_NeetOutMaterial.MaterialCode}-需求:{view_NeetOutMaterial.NeetQuantity}-工单:{view_NeetOutMaterial.OrderNo}-箱盒:{view_NeetOutMaterial.BoxPositionCode}";
                await LogNote_res.InsertAsync(lognote);
                //添加mes出库信息
                await PutOutOrder_res.FirstOrDefaultAsync(x => x.PutOutOrderCode == view_NeetOutMaterial.OrderNo);
                string newConsumer_MaterialId = ExtendRandom.CreateRandom();
                CustomOutRep customOutRep = new CustomOutRep();
                customOutRep.BILLNO = view_NeetOutMaterial.OrderNo;
                customOutRep.MATERIALCODE = view_NeetOutMaterial.MaterialCode;
                customOutRep.BATCH = view_NeetOutMaterial.Batch;
                customOutRep.QTY = (int)view_NeetOutMaterial.NeetQuantity;
                customOutRep.BARCODEOD = view_NeetOutMaterial.Consumer_MaterialId;
                customOutRep.BARCODENEW = newConsumer_MaterialId;
                customOutRep.PLANT = "CN11";
                customOutRep.DETAILID = view_NeetOutMaterial.DETAILID;
                customOutRep.JPID = view_NeetOutMaterial.JPID;
                customOutRep.CreateTime = DateTime.Now;
                await CustomOutRep_res.InsertAsync(customOutRep);
                view_NeetOutMaterial.Consumer_MaterialId = newConsumer_MaterialId;
                if (!OrderBatchCheck)
                {
                    return new ApiResponse($"当前这批订单已经全部结束", true, view_NeetOutMaterial);
                }
                if (materialBase.Quantity == 0)
                {
                    await UnitOfWorkManager.Current.SaveChangesAsync();
              
                    await Mediator.Publish(new PostNotification(materialBase.Consumer_MaterialId));//发布事务使用
                }
           
                return new ApiResponse($"取料成功,批次单据:{OrderBatch},请取走物料", true, view_NeetOutMaterial);
            }
            catch (SqlException ex)
            {
                loginHelper.LoginAsync(input, $"Sq+DeleteMaterial" + ex.Message);
                return new ApiResponse("数据库连接异常请稍后再试", false, null);
            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(input, "DeleteMaterial"+ex);
                return new ApiResponse("ERROR-DeleteMaterial", false, ex);
            }
        }
        public async Task<ApiResponse> UpdateState_ByWarehouselineId(InPut_BaseService17 InPut)//更新货位状态
        {
            try
            {
                WarehouseLine warehouseLine = await WarehouseLine_res.FirstOrDefaultAsync(x => x.Id_WarehouseLine == InPut.Id_WarehouseLine);
                if (warehouseLine == null)
                {
                    return new ApiResponse("未查询到库位", false, null);
                }
                warehouseLine.IsEnable = InPut.IsEnable;
                await WarehouseLine_res.UpdateAsync(warehouseLine);
                return new ApiResponse("更新成功", true, null);
            } catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "UpdateState_ByWarehouselineId");
                return new ApiResponse("ERROR-UpdateState_ByWarehouselineId", false, ex);
            }


        }
        public async Task<ApiResponse> UpdateState_ByInlethouselineId(InPut_BaseService18 InPut)//更新入口状态
        {
            try
            {
                InlethouseLine inlethouseLine = await Inlethouseline_res.FirstOrDefaultAsync(x => x.Id_InlethouseLine == InPut.Id_InlethouseLine);
                if (inlethouseLine == null)
                {
                    return new ApiResponse("未查询到库位", false, null);
                }
                inlethouseLine.IsEnable = InPut.IsEnable;
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                return new ApiResponse("更新成功", true, null);
            } catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "UpdateState_ByInlethouselineId");
                return new ApiResponse("ERROR-UpdateState_ByInlethouselineId", false, ex);
            }

        }
        public async Task<ApiResponse> UpdateNeetQuantity(InPut_BaseService19 InPut)//修改出库数量
        {
            try
            {
                NeetOutMaterial neetOutMaterial = await context.neetOutMaterials.Include(x => x.Material).FirstOrDefaultAsync(x => x.Id_NeetOutMaterial == InPut.Id_NeetOutMaterial);
                if (neetOutMaterial == null)
                {
                    return new ApiResponse("未查询到出库需求", false, null);
                }
                //updateneetoutmaterial
                neetOutMaterial.NeetQuantity = InPut.NeetQuantity;
                await NeetOutMaterial_res.UpdateAsync(neetOutMaterial);
                //CREATE  LOG
                lognote lognote = new lognote();
                lognote.DateTime = DateTime.Now;
                lognote.User = User.UserName;
                lognote.Type = "修改";
                lognote.Note = $"物料Id:{neetOutMaterial.Material.Consumer_MaterialId}-修改数量:{InPut.NeetQuantity}-工单:{neetOutMaterial.OrderNo}";
                await LogNote_res.InsertAsync(lognote);
                return new ApiResponse($"修改成功{neetOutMaterial.Material.Consumer_MaterialId}", true, null);
            } catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "UpdatManualQuantity");
                return new ApiResponse("ERROR-UpdatManualQuantity", false, ex);
            }

        }
        public async Task<ApiResponse> AllocationOrder(InPut_BaseService20 InPut)//分配出库工单-添加需出料
        {
            try
            {
                List<PutOutOrder> putOutOrders = await PutOutOrder_res.GetListAsync(x => x.Symbol == InPut.Symbol && x.State == "待分配");
                if (putOutOrders.Count == 0)
                {
                    return new ApiResponse("不存在/或已分配的工单", false, null);
                }
                List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x => x.Islock == false && x.BoxPosition.TheBoxGrid.TheBox.WarehouseLine != null);
                materialBases = materialBases.Where(x => putOutOrders.Any(y => y.Batch == x.Batch && y.MaterialCode == x.MaterialCode)).ToList();

                List<NeetOutMaterial> neetOutMaterials = new List<NeetOutMaterial>();
                foreach (var putOutOrder in putOutOrders)
                {
                    double OutBoundQuantity = putOutOrder.OutBoundQuantity;
                    materialBases = materialBases.OrderBy(x => x.CreatedDate).ToList();
                    foreach (var materialBase in materialBases)
                    {
                        if (materialBase.Islock || materialBase.MaterialCode != putOutOrder.MaterialCode && materialBase.Batch != putOutOrder.Batch)
                        {
                            continue;
                        }
                        if (OutBoundQuantity <= 0)
                        {
                            break;
                        }
                        NeetOutMaterial neetOutMaterial = new NeetOutMaterial();
                        double quantity;
                        if (materialBase.Quantity <= OutBoundQuantity)
                        {
                            quantity = (int)materialBase.Quantity;
                        }
                        else
                        {
                            quantity = OutBoundQuantity;
                        }
                        neetOutMaterial = neetOutMaterial.AddNeetOutMaterial(materialBase, putOutOrder.Symbol, quantity, null, null, null, InPut.Machine);
                        neetOutMaterials.Add(neetOutMaterial);
                        materialBase.Islock = true;
                        materialBase.NeetOutMaterials.Add(neetOutMaterial);
                        OutBoundQuantity = OutBoundQuantity - quantity;
                    }
                    if (OutBoundQuantity <= 0)
                    {
                        putOutOrder.State = "已分配";
                    }
                    else
                    {
                        putOutOrder.State = "缺料";
                    }

                }
                await PutOutOrder_res.UpdateManyAsync(putOutOrders);
                await NeetOutMaterial_res.InsertManyAsync(neetOutMaterials);
                return new ApiResponse("分配成功", true, null);
            } catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "AllocationOrder");
                return new ApiResponse("ERROR-AllocationOrder", false, ex);
            }

        }
        public async Task<ApiResponse> Deallocate(string Symbol)//解除分配
        {


            try
            {
                TaskOrder taskOrder = await TaskOrder_res.FirstOrDefaultAsync(x => x.OrderNo == Symbol);
                if (taskOrder != null)
                {
                    return new ApiResponse("已经下架的物料无法解除分配", false, null);
                }
                //update putoutorder
                List<PutOutOrder> putOutOrders = await PutOutOrder_res.GetListAsync(x => x.Symbol == Symbol);
                putOutOrders.ForEach(x =>
                {
                    x.State = "待分配";
                });
                await PutOutOrder_res.UpdateManyAsync(putOutOrders);
                //update material
                List<NeetOutMaterial> neetOutMaterials = await NeetOutMaterial_res.GetListAsync(x => x.OrderNo == Symbol);
                List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x => x.NeetOutMaterials.Any(y => y.OrderNo == Symbol));
                materialBases.ForEach(x =>
                {
                    x.Islock = false;
                });
                await MaterialBase_res.UpdateManyAsync(materialBases);
                //delete neetoutmaterials
                await NeetOutMaterial_res.DeleteManyAsync(neetOutMaterials);
                return new ApiResponse("解除成功", true, null);
            } catch (Exception ex)
            {
                Logger.LogError(Symbol, "Deallocate");
                return new ApiResponse("ERROR-Deallocate", false, ex);
            }



        }
        public async Task<ApiResponse> AllocationOrderAgvTask(InPut_BaseService21 InPut)
        {
            try
            {
                List<NeetOutMaterial> neetOutMaterials = await context.neetOutMaterials.Include(x => x.Material).ThenInclude(x => x.BoxPosition).
                                  ThenInclude(x => x.TheBoxGrid).ThenInclude(x => x.TheBox).Where(x => x.OrderNo == InPut.Symbol).ToListAsync();
                List<PutOutOrder> putOutOrders = await PutOutOrder_res.GetListAsync(x => x.Symbol == InPut.Symbol);
                if (neetOutMaterials.Count == 0)
                {
                    return new ApiResponse($"请先分配再下架", false, null);
                }
                List<MaterialBase> materialBases = await context.materialBases.Include(x => x.BoxPosition).ThenInclude(x => x.TheBoxGrid).
                                                  ThenInclude(x => x.TheBox).ThenInclude(x => x.WarehouseLine).Where(x => x.NeetOutMaterials.Any(y => y.OrderNo == InPut.Symbol)).ToListAsync();
                //查验任务中已存在的箱盒
                List<string> BoxCodes = materialBases.Select(x => x.BoxPosition.TheBoxGrid.TheBox.BoxCode).ToList();
                BoxCodes = BoxCodes.Distinct().ToList();
                BoxCodes = await context.taskOrders.Include(x => x.Box).Where(x => BoxCodes.Any(y => y == x.Box.BoxCode)).Select(x => x.Box.BoxCode).ToListAsync();
                if (BoxCodes.Count > 0)
                {
                    return new ApiResponse($"料盒{string.Join(",", BoxCodes)}已经分配到其他下架任务了", false, null);
                }
                //create taskerorder updateinlethouse
                InlethouseLine inlethouseLine = await Inlethouseline_res.FirstOrDefaultAsync(x => x.InlethouseLineCode == InPut.InlethouseCode);
                if (inlethouseLine == null)
                {
                    return new ApiResponse($"查询不到的出口", false, null);
                }
                materialBases = materialBases.DistinctBy(x => x.BoxPosition.TheBoxGrid.TheBox.BoxCode).ToList();
                List<TaskOrder> taskorders = new List<TaskOrder>();
                foreach (var item in materialBases)
                {
                    TaskOrder taskOrder = new TaskOrder();
                    taskOrder = taskOrder.AddTaskOrder("出库", item.BoxPosition.TheBoxGrid.TheBox.Id_Box,
                        item.BoxPosition.TheBoxGrid.TheBox.WarehouseLine.WarehouseLineCode, InPut.InlethouseCode,
                        InPut.Symbol, 0, 0, InPut.Machine);
                    item.BoxPosition.TheBoxGrid.TheBox.TaskOrder = taskOrder;
                    item.BoxPosition.TheBoxGrid.TheBox.Machine = InPut.Machine.ToString();
                    inlethouseLine.IsOccupy = true;
                    await Box_res.UpdateAsync(item.BoxPosition.TheBoxGrid.TheBox);
                    taskorders.Add(taskOrder);
                }
                //update PutOutOrder
                putOutOrders.ForEach(x =>
                {
                    x.State = "已分配下架";
                });
                await PutOutOrder_res.UpdateManyAsync(putOutOrders);
                await NeetOutMaterial_res.UpdateManyAsync(neetOutMaterials);
                await TaskOrder_res.InsertManyAsync(taskorders);
                await MaterialBase_res.UpdateManyAsync(materialBases);
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                return new ApiResponse("料盒分配下架", true, null);
            } catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "AllocationOrderAgvTask");
                return new ApiResponse("ERROR-AllocationOrderAgvTask", false, ex);
            }

        }//分配出库工单-添加agv
        public async Task<ApiResponse> Create_SowingWall(InPut_BaseService22 InPut)
        {
            try
            {
                SowingWall sowingWall = new SowingWall();
                sowingWall = sowingWall.AddSowingWall(InPut.SowingWall_Name, InPut.SowingWall_Code, InPut.Xaxis, InPut.Yaxis, InPut.Machine);
                if (sowingWall == null)
                {
                    return new ApiResponse("添加失败", false, null);
                }
                await SowingWall_res.InsertAsync(sowingWall);
                return new ApiResponse("添加成功", false, null);
            } catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "Create_SowingWall");
                return new ApiResponse("ERROR-Create_SowingWall", false, ex);
            }


        }//配置播种箱
        public async Task<ApiResponse> Update_SowingWall(string SowingWallLine_Name)
        {
            SowingWallLine sowingWallLine = await SowingWallLine_res.FirstOrDefaultAsync(x => x.SowingWallLine_Name == SowingWallLine_Name);
            if (sowingWallLine == null)
            {
                return new ApiResponse("未查询到该播种位", false, null);
            }
            sowingWallLine = sowingWallLine.Update_IsOccupy_IsLight_Info(SowingWallLine_Name);
            await SowingWallLine_res.UpdateAsync(sowingWallLine);
            //create log
            lognote lognote = new lognote()
            {
                DateTime = DateTime.Now,
                Type = "清空播种位",
                User = User.UserName,
                Note = $"位置:{sowingWallLine.SowingWallLine_Name}+单号:{sowingWallLine.Info}"
            };
            await LogNote_res.InsertAsync(lognote);
            return new ApiResponse("清除成功", true, null);
        }//更新播种位
        public async Task<ApiResponse> moveContainer_wms(InPut_EssService5 InPut)
        {
            lognote lognote3 = new lognote()
            {
                DateTime = DateTime.Now,
                BoxCode = InPut.BoxCode,
                Type = "输送线",
                User = " 输送线",
                Note = $"输送线上架-1-TaskType{InPut.TaskType}-slot{InPut.SlotCode}"
            };
            await LogNote_res.InsertAsync(lognote3);
            //上架-1
            if (InPut.TaskType == "上架-1")
            {

                loginHelper.LoginInfoAsync("sss", $"输送线上架-1+slotcode:{InPut.SlotCode}" +
    $"containercode:{InPut.BoxCode}taskType:{InPut.TaskType}Direction:{InPut.Direction}");
                bool res = await toOutSideInterFace.moveContainer(InPut.BoxCode, InPut.Direction, InPut.SlotCode);
                if (res)
                {
                    lognote lognote = new lognote()
                    {
                        DateTime = DateTime.Now,
                        BoxCode = InPut.BoxCode,
                        Type = InPut.TaskType,
                        User = User.UserName,
                        Note = $"输送线上架-1-Direction{InPut.Direction}-slot{InPut.SlotCode}"
                    };
                    await LogNote_res.InsertAsync(lognote);
                    return new ApiResponse("输送线流动成功", true, null);
                    //moveContainerInfo.SoltCode = "1-6";
                    //    await MoveContainerInfo_res.UpdateAsync(moveContainerInfo);
                }
            }
            //上架-2
            if (InPut.TaskType == "上架-2")
            {

                loginHelper.LoginInfoAsync("sss", $"输送线上架-2+slotcode:{InPut.SlotCode}" +
                        $"containercode:{InPut.BoxCode}taskType:{InPut.TaskType}Direction:{InPut.Direction}");
                bool res = await toOutSideInterFace.moveContainer(InPut.BoxCode, InPut.Direction, InPut.SlotCode);
                if (res)
                {
                    lognote lognote = new lognote()
                    {
                        DateTime = DateTime.Now,
                        BoxCode = InPut.BoxCode,
                        Type = InPut.TaskType,
                        User = User.UserName,
                        Note = $"输送线上架-2-Direction{InPut.Direction}-slot{InPut.SlotCode}"
                    };
                    await LogNote_res.InsertAsync(lognote);
                    //await MoveContainerInfo_res.DeleteAsync(moveContainerInfo);
                    return new ApiResponse("输送线流动成功", true, null);
                }


            }
            //下架-1
            if (InPut.TaskType == "下架-1")
            {
                loginHelper.LoginInfoAsync("sss", $"输送线下架-1+slotcode:{InPut.SlotCode}" +
                $"containercode:{InPut.BoxCode}taskType:{InPut.TaskType}Direction:{InPut.Direction}");
                bool res = await toOutSideInterFace.moveContainer(InPut.BoxCode, InPut.Direction, InPut.SlotCode);
                if (res)
                {
                    lognote lognote = new lognote()
                    {
                        DateTime = DateTime.Now,
                        BoxCode = InPut.BoxCode,
                        Type = InPut.TaskType,
                        User = User.UserName,
                        Note = $"输送线下架-1-Direction{InPut.Direction}-slot{InPut.SlotCode}"
                    };
                    await LogNote_res.InsertAsync(lognote);
                    //await MoveContainerInfo_res.DeleteAsync(moveContainerInfo);
                    return new ApiResponse("输送线流动成功", true, null);
                }

            }
            //下架-2
            if (InPut.TaskType == "下架-2")
            {
                loginHelper.LoginInfoAsync("sss", $"输送线下架-2+slotcode:{InPut.SlotCode}" +
$"containercode:{InPut.BoxCode}taskType:{InPut.TaskType}Direction:{InPut.Direction}");
                bool res = await toOutSideInterFace.moveContainer(InPut.BoxCode, InPut.Direction, InPut.SlotCode);
                if (res)
                {
                    lognote lognote = new lognote()
                    {
                        DateTime = DateTime.Now,
                        BoxCode = InPut.BoxCode,
                        User = User.UserName,
                        Type = InPut.TaskType,
                        Note = $"输送线下架-2-Direction{InPut.Direction}-slot{InPut.SlotCode}"
                    };
                    await LogNote_res.InsertAsync(lognote);
                    return new ApiResponse("输送线流动成功", true, null);
                }



            }
            //移位-2
            if (InPut.TaskType == "移位-2")
            {
                loginHelper.LoginInfoAsync("ssss", $"输送线移位-2+slotcode:{InPut.SlotCode}" +
                    $"containercode:{InPut.BoxCode}taskType:{InPut.TaskType}Direction:{InPut.Direction}");
                bool res = await toOutSideInterFace.moveContainer(InPut.BoxCode, InPut.Direction, InPut.SlotCode);
                if (res)
                {
                    lognote lognote = new lognote() { DateTime = DateTime.Now,
                        User = User.UserName,
                        BoxCode = InPut.BoxCode,
                        Type = InPut.TaskType, Note = $"输送线移位-2-Direction{InPut.Direction}-slot{InPut.SlotCode}" };
                    await LogNote_res.InsertAsync(lognote);
                    return new ApiResponse("输送线流动成功", true, null);
                }
            }
            //移位-1
            if (InPut.TaskType == "移位-1")
            {
                loginHelper.LoginInfoAsync("sss", $"输送线移位-1+slotcode:{InPut.SlotCode}" +
                 $"containercode:{InPut.BoxCode}taskType:{InPut.TaskType}Direction:{InPut.Direction}");
                bool res = await toOutSideInterFace.moveContainer(InPut.BoxCode, InPut.Direction, InPut.SlotCode);
                if (res)
                {
                    lognote lognote = new lognote() { DateTime = DateTime.Now,
                        BoxCode = InPut.BoxCode,
                        Type = InPut.TaskType,
                        User = User.UserName,
                        Note = $"输送线移位-1-Direction{InPut.Direction}-slot{InPut.SlotCode}" };
                    await LogNote_res.InsertAsync(lognote);
                    return new ApiResponse("输送线流动成功", true, null);
                }


            }
            return new ApiResponse("输送线流动失败", false, null);
        }//输送线移动容器
        public async Task<ApiResponse> DeleteMoveContainer(string boxCode)//删除输送线任务
        {
            await MoveContainerInfo_res.DeleteAsync(x => x.BoxCode == boxCode);
            return new ApiResponse("删除成功", true, null);
        }
        public async Task<ApiResponse> SendCustomerOutRep(string Consumer_MaterialId)//出库回传
        {
            PutOutOrder putoutorder = await PutOutOrder_res.FirstOrDefaultAsync(x => x.PutOutOrderCode == Consumer_MaterialId);
            if (putoutorder == null)
            {
                return new ApiResponse("未查询到单号,回传失败", false, null);
            }
            bool res = await PutOutOrder_res.AnyAsync(x => x.PutOutOrderCode == putoutorder.PutOutOrderCode && x.IsFinish == false);
            if (res)
            {
                return new ApiResponse("工单还未全部分配,不回传", false, null);
            }
            bool NeetOutCheckres = await NeetOutMaterial_res.AnyAsync(x => x.OrderNo == putoutorder.PutOutOrderCode);
            if (NeetOutCheckres)
            {
                return new ApiResponse("物料还未全部拣配完,不回传", false, null);
            }
            List<CustomOutRep> customOutReps = await CustomOutRep_res.GetListAsync(x => x.BILLNO == putoutorder.PutOutOrderCode && x.IsSend == false);
            PutOutOrder putOutOrder = await PutOutOrder_res.FirstOrDefaultAsync(x => x.PutOutOrderCode == putoutorder.PutOutOrderCode);

            Custom_InPut2 custom_InPut2 = new Custom_InPut2();
            List<model> modelDto = ObjectMapper.Map<List<CustomOutRep>, List<model>>(customOutReps);
            custom_InPut2.model = modelDto;
            //custom_InPut2.ForceCloseList = new List<ForceCloseList>() { new ForceCloseList() { DETAILID = null, JPID = null } };
            bool Customreturn = await toOutSideInterFace.RBTOutRep(custom_InPut2);
            if (Customreturn)
            {
             
                foreach (var item in customOutReps)
                {
                    item.IsSend = true;
                    item.UpdateTime = DateTime.Now;
                }
                await CustomOutRep_res.UpdateManyAsync(customOutReps);
                SowingWallLine sowingWallLine = await SowingWallLine_res.FirstOrDefaultAsync(x => x.Info == putoutorder.PutOutOrderCode);
                if (sowingWallLine != null)
                {
                    sowingWallLine.OrderIsfinish = true;
                    Tuple<string, HubConnection> tuple = await SingalrMethod.GetConnectionAsync("灭灯", null, null);
                    await tuple.Item2.StopAsync();

                    await SowingWallLine_res.UpdateAsync(sowingWallLine);
                }
                return new ApiResponse("回传成功,工单结束", true, null);
            }
            else
            {
                lognote lognote = new lognote() { Type = "异常", Note = $"回传失败-{putOutOrder.PutOutOrderCode}-Consumer_materialid{Consumer_MaterialId}", User = User.UserName, DateTime = DateTime.Now };
                return new ApiResponse("回传失败", false, null);
            }

        }
        public async Task<ApiResponse> Manual_FinishOrder(Guid PutOutOrder_id)//关闭工单
        {
            PutOutOrder putOutOrder = await PutOutOrder_res.FirstOrDefaultAsync(x => x.PutOutOrder_id == PutOutOrder_id);
            if (putOutOrder == null)
            {
                return new ApiResponse("未查询到工单", false, null);
            }
            bool res = await NeetOutMaterial_res.AnyAsync(x => x.OrderNo == putOutOrder.PutOutOrderCode);
            if (res)
            {
                return new ApiResponse("还有物料未完成,无法关闭", false, null);
            }
            List<PutOutOrder> putOutOrders = await PutOutOrder_res.GetListAsync(x => x.PutOutOrderCode == putOutOrder.PutOutOrderCode && x.IsFinish == false);
            //notify mes
            List<CustomOutRep> customOutReps = await CustomOutRep_res.GetListAsync(x => x.BILLNO == putOutOrder.PutOutOrderCode
            && x.IsSend == false);
            Custom_InPut2 custom_InPut2 = new Custom_InPut2();
            List<model> modelDto = ObjectMapper.Map<List<CustomOutRep>, List<model>>(customOutReps);
            if (modelDto.Count > 0)
            {
                custom_InPut2.model = modelDto;
            }

            List<ForceCloseList> forceCloseLists = ObjectMapper.Map<List<PutOutOrder>, List<ForceCloseList>>(putOutOrders);
            custom_InPut2.ForceCloseList = forceCloseLists;

            bool Customreturn = await toOutSideInterFace.RBTOutRep(custom_InPut2);
            var json = JsonConvert.SerializeObject(custom_InPut2);
            if (!Customreturn)
            {
                return new ApiResponse("mes请求失败,无法关闭", false, json);
            }


            //update putOutOrders
            putOutOrders.ForEach(x => { x.IsFinish = true; x.UpdateTime = DateTime.Now; x.State = "手动关闭"; });
            await PutOutOrder_res.UpdateManyAsync(putOutOrders);
            //update CustomOutRep
            customOutReps.ForEach(x => { x.IsSend = true; x.UpdateTime = DateTime.Now; });
            await CustomOutRep_res.UpdateManyAsync(customOutReps);

            //create log
            lognote lognote = new lognote() { Type = "修改", Note = $"手动关闭订单-{putOutOrder.PutOutOrderCode}", User = User.UserName, DateTime = DateTime.Now };
            await LogNote_res.InsertAsync(lognote);
            return new ApiResponse("手动完成", true, null);
        }
        public async Task<ApiResponse> UpdatManualQuantity(InPut_BaseService24 InPut)//设置手动出库数量
        {
            //update materialBase
            MaterialBase materialBase = await MaterialBase_res.FirstOrDefaultAsync(x => x.Id_Materialbase == InPut.Id_Materialbase);
            if (materialBase == null)
            {
                return new ApiResponse("未查询到物料", false, null);
            }
            if (materialBase.Islock)
            {
                return new ApiResponse("物料已锁定,无法修改", false, null);
            }
            if (InPut.Poundage == "0")
            {
                materialBase.Poundage = null;
            }
            if (!string.IsNullOrEmpty(InPut.Poundage) && int.Parse(InPut.Poundage) > 0)
            {
                if (int.Parse(InPut.Poundage) > materialBase.Quantity)
                {
                    return new ApiResponse("数量已超", false, null);
                }
                materialBase.Poundage = InPut.Poundage;

            }

            await MaterialBase_res.UpdateAsync(materialBase);
            //create log
            lognote lognote = new lognote() { Type = "修改", Note = $"手动出库数量-物料id:{materialBase.Consumer_MaterialId}-数量:{materialBase.Poundage}",
                User = User.UserName, DateTime = DateTime.Now };
            await LogNote_res.InsertAsync(lognote);

            return new ApiResponse("设置成功", true, null);
        }
        public async Task<ApiResponse> UpdateMaterialQuantity(InPut_BaseService25 InPut)//修改数量
        {
            MaterialBase materialBase = await MaterialBase_res.FirstOrDefaultAsync(x => x.Id_Materialbase == InPut.Id_Materialbase);
            if (materialBase == null)
            {
                return new ApiResponse("未查询到物料", false, null);
            }
            bool res = await NeetOutMaterial_res.AnyAsync(x => x.Material == materialBase);
            if (res)
            {
                return new ApiResponse("该物料当前正在出库,无法修改", false, null);
            }
            if (InPut.Quantity == 0)
            {
                await MaterialBase_res.DeleteAsync(materialBase);
            }
            else
            {
                materialBase.Quantity = InPut.Quantity;
                materialBase.VirtualQuantity = InPut.Quantity;
                await MaterialBase_res.UpdateAsync(materialBase);
            }
            // update mes
            InPut_CunsumerService6 InPutCustom = new InPut_CunsumerService6();
            InPutCustom.PlantCode = "CN11";
            InPutCustom.OperateUser = User.UserName;
            InPutCustom.BusinessType = "快捷调整";
            InPutCustom.BarCode = materialBase.Consumer_MaterialId;
            InPutCustom.Remark = "调整备注";
            InPutCustom.Num = (int)InPut.Quantity;
            await toOutSideInterFace.QuickAdjust(InPutCustom);
            //create log
            lognote lognote = new lognote()
            {
                Type = "修改",
                Note = $"物料数量-物料id:{materialBase.Consumer_MaterialId}-数量:{InPut.Quantity}",
                User = User.UserName,
                DateTime = DateTime.Now
            };
            await LogNote_res.InsertAsync(lognote);
            return new ApiResponse("设置成功", true, null);
        }
        public async Task<ApiResponse> CheckBoxMaterial(string BoxPosition)//检查箱内物料
        {
            if (string.IsNullOrEmpty(BoxPosition))
            {
                return new ApiResponse("箱码为空", false, null);
            }
            bool res = await context.View_Materials.AnyAsync(x => x.BoxPositionCode.Contains(BoxPosition.Substring(0, 10)));
            if (!res)
            {
                return new ApiResponse($"{BoxPosition.Substring(0, 10)}箱内已空", true, null);
            }
            return new ApiResponse("还有物料", false, null);
        }
        public async Task<ApiResponse> Start_StockTaking(InPut_BaseService26 InPut)//盘点执行
        {
            bool checkres = await TaskOrder_res.AnyAsync(x => x.Type == "出库");
            if (checkres)
            {
                return new ApiResponse("当前有出库任务未完成", false, null);
            }
            //List<CustomCheckList> customCheckLists = await context.customCheckLists.Where(x => InPut.CustomCheckList_Id.All(y=>y==x.CustomCheckList_Id)).ToListAsync();
            //customCheckLists = customCheckLists.DistinctBy(x => x.Consumer_MaterialId).ToList();
            //List<MaterialBase> materialBases=  await context.materialBases.Include(x=>x.BoxPosition).ThenInclude(x=>x.TheBoxGrid).
            //                                   ThenInclude(x=>x.TheBox).ThenInclude(x=>x.WarehouseLine).
            //                                   Where(x=>customCheckLists.Any(y=>y.Consumer_MaterialId==x.Consumer_MaterialId)
            //                                   &&x.BoxPosition.TheBoxGrid.TheBox.WarehouseLine!=null). ToListAsync();


            // 步骤1：获取符合条件的 CustomCheckList
            var customCheckLists = await context.customCheckLists
               .Where(x => InPut.CustomCheckList_Id.Contains(x.CustomCheckList_Id))
               .ToListAsync();

            // 步骤2：提取去重后的 Consumer_MaterialId
            var consumerMaterialIds = customCheckLists
                .DistinctBy(x => x.Consumer_MaterialId)
                .Select(x => x.Consumer_MaterialId)
                .ToList();

            // 步骤3：查询关联的 MaterialBase
            var materialBases = await context.materialBases
                .Include(x => x.BoxPosition)
                    .ThenInclude(x => x.TheBoxGrid)
                    .ThenInclude(x => x.TheBox)
                    .ThenInclude(x => x.WarehouseLine)
                .Where(x =>
                    consumerMaterialIds.Contains(x.Consumer_MaterialId) &&
                    x.BoxPosition.TheBoxGrid.TheBox.WarehouseLine != null
                )
                .ToListAsync();
            //update CustomCheckList
            foreach (var item in customCheckLists)
            {
                if (materialBases.Any(x => x.Consumer_MaterialId == item.Consumer_MaterialId))
                {

                    item.IsCheck = true;
                    item.IsExist = true;
                }
                else
                {
                    item.IsCheck = false;
                    item.IsExist = false;
                }
                item.UpdateTime = DateTime.Now;
            }
            //create Taskorder
            materialBases = materialBases.DistinctBy(x => x.BoxPosition.TheBoxGrid.TheBox.WarehouseLine).ToList();
            List<TaskOrder> taskOrders = new List<TaskOrder>();
            int taskpriority = 1000;
            foreach (var item in materialBases)
            {
                TaskOrder taskOrder = new TaskOrder();
                taskOrder = taskOrder.AddTaskOrder("出库", item.BoxPosition.TheBoxGrid.TheBox.Id_Box,
                                            item.BoxPosition.TheBoxGrid.TheBox.WarehouseLine.WarehouseLineCode,
                                            "LT_CONVEYOR_INPUT:POINT:6930:8103", "盘点出库", GlobalVariable.grouppriority, taskpriority, InPut.Machine);

                taskpriority--;
                taskOrders.Add(taskOrder);
            }
            await context.AddRangeAsync(taskOrders);
            await context.SaveChangesAsync();
            return new ApiResponse("已生成下架任务", true, null);

        }
        public async Task<ApiResponse> CheckView_Box_Warehoueline(IFormFile excelStream)//库存核对
        {

            // 使用EPPlus读取Excel
            using var stream = new MemoryStream();
            await excelStream.CopyToAsync(stream); // 将IFormFile转换为MemoryStream

            using var package = new ExcelPackage(stream);
            var worksheet = package.Workbook.Worksheets[0]; // 第一个工作表
                                                            // 检查工作表数量

            if (package.Workbook.Worksheets.Count == 0)

            {
                return new ApiResponse("没有工作表", true, null);

            }
            // 转换为DataTable
            DataTable dt = new DataTable();
            foreach (var firstRowCell in worksheet.Cells[1, 1, 1, worksheet.Dimension.End.Column])
            {
                dt.Columns.Add(firstRowCell.Text); // 第一行为列名
            }

            for (int row = 2; row <= worksheet.Dimension.End.Row; row++) // 从第二行开始读数据
            {
                var newRow = dt.NewRow();
                for (int col = 1; col <= worksheet.Dimension.End.Column; col++)
                {
                    newRow[col - 1] = worksheet.Cells[row, col].Text;
                }
                dt.Rows.Add(newRow);
            }

            // 或者转换为对象列表（推荐）
            var stocks = new List<InventoryItem>();
            for (int row = 1; row <= worksheet.Dimension.End.Row; row++)
            {
                stocks.Add(new InventoryItem
                {
                    BoxCode = worksheet.Cells[row, 1].Text,
                    WareHouseLineCode = worksheet.Cells[row, 2].Text,

                });
            }
            var view_Box_Warehouses = await context.View_Box_WarehouseLines.ToListAsync();
            List<string> Unterschied = new List<string>();

            if (stocks.Count < view_Box_Warehouses.Count)
            {
                // 提取所有 BoxCode 的集合
                var boxCodesInList2 = stocks.Select(i => i.BoxCode).ToHashSet();

                // 找出     存在 view_Box_Warehouses 中不存在于 stocks 的项
                var onlyInList1 =
                view_Box_Warehouses
                    .Where(i => !boxCodesInList2.Contains(i.BoxCode))
                    .ToList();
                Unterschied.AddRange(onlyInList1.Select(x => x.BoxCode));
            }
            foreach (var item in stocks)
            {
                if (view_Box_Warehouses.All(x => !x.BoxCode.Contains(item.BoxCode)))
                {
                    Unterschied.Add(item.BoxCode);
                    continue;
                }
                else
                {
                    if (!view_Box_Warehouses.Any(x => x.BoxCode == item.BoxCode && x.WarehouseLineCode == item.WareHouseLineCode))
                    {
                        Unterschied.Add(item.BoxCode);
                        continue;
                    }

                }
            }
            return new ApiResponse("核对完成", true, Unterschied);
        }
        public async Task<ApiResponse> GetOrderNo(string BoxCode)//根据箱号找单号/故障清除
        {
            View_TaskOrder view_TaskOrder = await context.View_TaskOrders.FirstOrDefaultAsync(x => x.BoxCode == BoxCode && x.Type == "出库");
            if (view_TaskOrder == null)
            {
                Box box = await context.boxs.FirstOrDefaultAsync(x => x.BoxCode == BoxCode);
                if (box != null)
                {
                    box.WarehouseLine = null;
                    box.Id_WarehouseLine = null;
                    WarehouseLine warehouseLine = await context.warehouseLines.Where(x => x.Box == box).FirstOrDefaultAsync();
                    if (warehouseLine != null)
                    {
                        warehouseLine.Box = null;
                        warehouseLine.IsOccupy = false;
                    }
                    lognote lognote = new lognote()
                    {
                        Type = "故障恢复",
                        Note = $"物料数量-BoxCode:{box.BoxCode}",
                        User = User.UserName,
                        DateTime = DateTime.Now
                    };
                    await LogNote_res.InsertAsync(lognote);
                    await context.SaveChangesAsync();
                    return new ApiResponse("清除成功", false, null);
                }
                return new ApiResponse("未查询到单号", false, null);
            }
            return new ApiResponse("查询成功", true, view_TaskOrder.TaskOrderCode);

        }
        public async Task<ApiResponse> LocationCheck()//库位检查
        {
            var warehouline = context.warehouseLines.Include(x => x.Box).Where(x => x.Box == null && x.IsOccupy == true).ToList();
            warehouline.ForEach(x => { x.IsOccupy = false; });
            await context.SaveChangesAsync();
            return new ApiResponse("核对完成", true, warehouline.Select(x => x.WarehouseLineCode));
        }
        public async Task<ApiResponse> UpdateBoxMaterial(InPut_BaseService7 inPut)  //物料更换料盒
        {
            MaterialBase materialBase = await MaterialBase_res.FirstOrDefaultAsync(x => x.Consumer_MaterialId == inPut.Consumer_MaterialId && x.Id_BoxPosition != null);
            if (materialBase == null)
            {
                return new ApiResponse($"未查询到此料", false, null);
            }
            BoxPosition boxPosition = await BoxPosition_res.FirstOrDefaultAsync(x => x.BoxPositionCode.Contains(inPut.BoxPositionCode) && x.MaterialBase == null);
            if (boxPosition == null)
            {
                return new ApiResponse($"{inPut.BoxPositionCode}已无空位", false, null);
            }
            //create material
            materialBase.UpdateTime = DateTime.Now;
            materialBase.PeoPle = User.UserName;
            materialBase.BoxPosition = boxPosition;
            await MaterialBase_res.UpdateAsync(materialBase);
            //create log
            lognote lognote = new lognote()
            {
                DateTime = DateTime.Now,
                Type = "更新料盒",
                User = User.UserName,
                Note = $"物料Id:{materialBase.Consumer_MaterialId}+物料编号:{materialBase.MaterialCode}+" +
                $"箱号:{boxPosition.BoxPositionCode}"
            };
            await LogNote_res.InsertAsync(lognote);
            return new ApiResponse("更换料盒成功", true, null);
        }
        public async Task<ApiResponse> DeleteCustomCheckList(List<Guid> guid)//删除盘点数据
        {
         List< CustomCheckList> customCheckList=       await CustomCheckList_res.GetListAsync(x=>guid.Any(y=>y==x.CustomCheckList_Id));
         if(customCheckList.Count==0)
         {
             return new ApiResponse("未查询到此数据", false, null);
         }
         await CustomCheckList_res.DeleteManyAsync(customCheckList);
            await LogNote_res.InsertAsync(new lognote()
            {
                DateTime = DateTime.Now,
                Type = "删除盘点数据",
                User = User.UserName,
                Note = $"盘点数据Id:{customCheckList.Select(x=>x.Consumer_MaterialId)}"
            });
         return new ApiResponse("删除成功", true, null);
        
        }
        public async Task<ApiResponse> IsReplenishment()//是否补料
        {
         List<PutOutOrder> putOutOrders=await  context.putOutOrder.Where(x=> x.State.Contains("缺料")).ToListAsync();
            foreach(var item in putOutOrders)
            {
               bool res=    await context.materialBases.AnyAsync(x=>x.MaterialCode==item.MaterialCode&&x.Quantity>=item.OutBoundQuantity);
                if (res)
                {
                    item.IsReplenishment = true;
                }
                
            }
            await context.SaveChangesAsync();
            return new ApiResponse("匹配成功", true, null);
        }
        public async Task<ApiResponse> GetConveyorline()//获取输送线料盒
        {
          int conveyor1=    await context.conveyorlines.Where(x=>x.Machine=="1").CountAsync();
          int conveyor2 = await context.conveyorlines.Where(x => x.Machine == "2").CountAsync();
          int taskOrder1 = await context.taskOrders.Where(x => x.Machine==1&&x.State=="已下发"&&x.Type=="出库").CountAsync();
          int taskOrder2 = await context.taskOrders.Where(x => x.Machine == 2 && x.State == "已下发" && x.Type == "出库").CountAsync();
          return new ApiResponse("获取成功", true, $"1#拣料台:有{conveyor1}个箱子已下发任务{taskOrder1}个,2#拣料台:有{conveyor2}个箱子已下发任务{taskOrder2}个");
        }
  


        //轮询事务
        public async Task<ApiResponse> SingleOutbount(Guid guid)//单次执行工单
        {
            List<PutOutOrder> putOutOrders = await context.putOutOrder.Where(x => x.PutOutOrder_id == guid && x.State.Contains("缺料")).ToListAsync();
            if (putOutOrders.Count == 0)
            {
                return new ApiResponse("没有需要出库的订单", false, null);
            }
            putOutOrders = putOutOrders.GroupBy(x => x.PollingCount).FirstOrDefault().ToList();
            putOutOrders = putOutOrders.GroupBy(x => x.MaterialCode).FirstOrDefault().ToList();
            List<MaterialBase> materialBases = await context.materialBases.Include(x => x.BoxPosition).ThenInclude(x => x.TheBoxGrid).
                                              ThenInclude(x => x.TheBox).ThenInclude(x => x.WarehouseLine).
                                              Where(x => x.Islock == false
                                              && x.MaterialCode == putOutOrders[0].MaterialCode).OrderBy(x => x.Batch).ToListAsync();// 不只查询在库的: &&x.BoxPosition.TheBoxGrid.TheBox.WarehouseLine != null
            //添加需要出的料
            List<NeetOutMaterial> neetOutMaterials = new List<NeetOutMaterial>();
            foreach (PutOutOrder order in putOutOrders)
            {
                foreach (var materialBase in materialBases)
                {
                    if (materialBase.VirtualQuantity == 0)
                    {
                        continue;
                    }
                    if (materialBase.VirtualQuantity >= order.VirtualOutBound)
                    {
                        neetOutMaterials.Add(new NeetOutMaterial
                        {
                            CreatedDate = DateTime.Now,
                            OrderNo = order.PutOutOrderCode,
                            NeetQuantity = order.VirtualOutBound,
                            DETAILID = order.DETAILID,
                            JPID = order.JPID,
                            Material = materialBase,
                            Machine = order.Machine
                        });
                        materialBase.VirtualQuantity = materialBase.VirtualQuantity - order.VirtualOutBound;
                        order.VirtualOutBound = order.VirtualOutBound - order.VirtualOutBound;
                        break;
                    }
                    else
                    {
                        neetOutMaterials.Add(new NeetOutMaterial
                        {
                            CreatedDate = DateTime.Now,
                            OrderNo = order.PutOutOrderCode,
                            NeetQuantity = materialBase.VirtualQuantity,
                            Material = materialBase,
                            DETAILID = order.DETAILID,
                            JPID = order.JPID,
                            Machine = order.Machine
                        });
                        order.VirtualOutBound = order.VirtualOutBound - materialBase.VirtualQuantity;
                        materialBase.VirtualQuantity = materialBase.VirtualQuantity - materialBase.VirtualQuantity;


                    }
                }
                if (order.VirtualOutBound > 0)
                {
                    order.State = $"缺料{order.VirtualOutBound}个:原订单{order.OutBoundQuantity}个";
                    order.PollingCount++;
                    order.UpdateTime = DateTime.Now;

                }
                else
                {
                    order.State = "已全部分配";
                    order.IsFinish = true;
                    order.UpdateTime = DateTime.Now;
                }
            }
            await context.AddRangeAsync(neetOutMaterials);
            await context.SaveChangesAsync();
            return new ApiResponse("分配成功", true, null);
        }
        public async Task<ApiResponse> Polling_OutBound()//轮询出库清单
        {
            try
            {

       
            List<PutOutOrder> putOutOrders = await context.putOutOrder.Where(x => x.IsFinish == false && !x.State.Contains("缺料")).OrderBy(x => x.PollingCount).ToListAsync();
            if (putOutOrders.Count == 0)
            {
                return new ApiResponse("没有需要出库的订单", false, null);
            }
            putOutOrders = putOutOrders.GroupBy(x => x.PollingCount).FirstOrDefault().ToList();
            List<View_NeetOutMaterial> view_NeetOutMaterialcheck = await context.View_NeetOutMaterials.ToListAsync();

            // 去掉和view_NeetOutMaterialcheck中Code字段相同的数据
            //var codesToRemove = view_NeetOutMaterialcheck.Select(x => x.MaterialCode).ToList();
            //putOutOrders = putOutOrders.Where(x => !codesToRemove.Contains(x.MaterialCode)).ToList();

            var putoutordercommon = putOutOrders.Where(order => view_NeetOutMaterialcheck.Any(view => view.MaterialCode == order.MaterialCode && view.OrderBatch != order.OrderBatch)).ToList();



            putOutOrders =putOutOrders.Where(order => view_NeetOutMaterialcheck.
               All(view => view.MaterialCode != order.MaterialCode || (view.MaterialCode == order.MaterialCode && view.OrderBatch == order.OrderBatch))).ToList();
            if (putoutordercommon.Count > 0 && putOutOrders.Count > 0)
            {
                lognote lognote = new lognote()
                {
                    DateTime = DateTime.Now,
                    User = "轮询",
                    Type = "工单重复验证",
                    // 使用 string.Join 将集合元素连接成字符串
                    Note = $"{string.Join(",", putoutordercommon.Select(x => x.OrderBatch))}code{string.Join(",", putoutordercommon.Select(x => x.MaterialCode))}+orders{string.Join(",", putOutOrders.Select(x => x.OrderBatch))}code{string.Join(",", putOutOrders.Select(x => x.MaterialCode))}"
                };
                await context.AddAsync(lognote);
            }


            //putOutOrders = putOutOrders.GroupBy(x => x.MaterialCode).Random().ToList();
            List<string> materialCodes = putOutOrders.Select(y => y.MaterialCode).Distinct().ToList();
            var excludedBoxPositionCodes = view_NeetOutMaterialcheck.Select(v => v.BoxPositionCode).Distinct().ToList();



            List<MaterialBase> materialBases = await context.materialBases.Include(x=>x.BoxPosition).ThenInclude(x=>x.TheBoxGrid).ThenInclude(x=>x.TheBox).
                                               Where(x => x.Islock == false
                                               && materialCodes.Any(y => y == x.MaterialCode)).OrderBy(x=>x.Consumer_MaterialId).ToListAsync();//这里加一个条件 去掉materialBases中BoxPosition的BoxPositionCode跟 view_NeetOutMaterialcheck中BoxPositionCode字段存在相同的数据
            //materialBases = materialBases.Where(x=>!excludedBoxPositionCodes.Any(y=>y!.Contains( x.BoxPosition.TheBoxGrid.TheBox.BoxCode))).ToList();//去掉已经在箱子里的料


            List<NeetOutMaterial> neetOutMaterials = new List<NeetOutMaterial>();
            foreach (PutOutOrder order in putOutOrders)
            {


                foreach (var materialBase in materialBases)
                {

        

                    //当前轮询的工单批次跟需拣配中批次不一致  并且 料盒还是同一料盒的情况
                    var view_neetCompare =   view_NeetOutMaterialcheck.Where(x=>x.OrderBatch!=order.OrderBatch).ToList();
                    if (view_neetCompare.Any(y => y.BoxPositionCode. Contains(materialBase.BoxPosition.TheBoxGrid.TheBox.BoxCode)))
                    {
                        continue;
                    }


                    if (materialBase.MaterialCode != order.MaterialCode)
                    {
                        continue;
                    }

                    if (materialBase.VirtualQuantity == 0)
                    {
                        continue;
                    }
                    if (materialBase.VirtualQuantity >= order.VirtualOutBound)
                    {
                        neetOutMaterials.Add(new NeetOutMaterial
                        {
                            CreatedDate = DateTime.Now,
                            OrderNo = order.PutOutOrderCode,
                            NeetQuantity = order.VirtualOutBound,
                            OrderBatch = order.OrderBatch,
                            DETAILID = order.DETAILID,
                            JPID = order.JPID,
                            Material = materialBase,
                            Machine = order.Machine,
                            printOrder = order.printOrder

                        });
                        materialBase.VirtualQuantity = materialBase.VirtualQuantity - order.VirtualOutBound;
                        order.VirtualOutBound = order.VirtualOutBound - order.VirtualOutBound;
                        break;
                    }
                    else
                    {
                        neetOutMaterials.Add(new NeetOutMaterial
                        {
                            CreatedDate = DateTime.Now,
                            OrderNo = order.PutOutOrderCode,
                            OrderBatch = order.OrderBatch,
                            NeetQuantity = materialBase.VirtualQuantity,
                            Material = materialBase,
                            DETAILID = order.DETAILID,
                            JPID = order.JPID,
                            Machine = order.Machine,
                            printOrder= order.printOrder
                        });
                        order.VirtualOutBound = order.VirtualOutBound - materialBase.VirtualQuantity;
                        materialBase.VirtualQuantity = materialBase.VirtualQuantity - materialBase.VirtualQuantity;


                    }
                }
                if (order.VirtualOutBound > 0)
                {
                    order.State = $"缺料{order.VirtualOutBound}个:原订单{order.OutBoundQuantity}个";
                    order.PollingCount++;
                    order.UpdateTime = DateTime.Now;

                }
                else
                {
                    order.State = "已全部分配";
                    order.IsFinish = true;
                    order.UpdateTime = DateTime.Now;
                }
            }

            await context.AddRangeAsync(neetOutMaterials);
            await context.SaveChangesAsync();

            }
            catch (SqlException ex)
            {
           

                loginHelper.LoginAsync(" ", $"Sq+Polling_OutBound" + ex.Message);

                return new ApiResponse("数据库连接异常请稍后再试", false, null);
            }
            catch(Exception ex)
            {
              
                loginHelper.LoginAsync(" ", $"Polling_OutBound" + ex.Message);
                return new ApiResponse("轮询出库异常请稍后再试", false, null);
            }
            return new ApiResponse("分配成功", true, null);
        }
        public async Task<ApiResponse> Polling_TaskOrder()//轮询task任务
        {
            int taskpriority = 1000;
            List<NeetOutMaterial> neetOutMaterials = await context.neetOutMaterials.
            Include(x => x.Material).ThenInclude(x => x.BoxPosition).
            ThenInclude(x => x.TheBoxGrid).ThenInclude(x => x.TheBox).ThenInclude(x => x.WarehouseLine)
            .Where(x => x.remark != "1").ToListAsync();
            List<TaskOrder> taskOrders = new List<TaskOrder>();
            foreach (var neetOutMaterial in neetOutMaterials)
            {

                //如果数据库有该任务的跳过
                bool res = await TaskOrder_res.AnyAsync(x => x.Box == neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox);
                if (res)
                {
                    continue;
                }
                //如果当前列表中已经有该任务则跳过
                bool res2 = taskOrders.Any(x => x.Box == neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox);
                if (res2)
                {
                    continue;
                }
                //如果不在库内则跳过

                bool res3= await NeetOutMaterial_res.AnyAsync(x => x.Id_NeetOutMaterial== neetOutMaterial.Id_NeetOutMaterial&&x.Material.BoxPosition.TheBoxGrid.TheBox.Id_WarehouseLine == null);
                if (res3)
                {
                    continue;
                }
                TaskOrder taskOrder = new TaskOrder();
                taskOrder = taskOrder.AddTaskOrder("出库", neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox.Id_Box,
                                             neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox.WarehouseLine.WarehouseLineCode,
                                            "LT_CONVEYOR_INPUT:POINT:6930:8103", neetOutMaterial.OrderNo, GlobalVariable.grouppriority, taskpriority, neetOutMaterial.Machine);
                taskOrders.Add(taskOrder);
                taskpriority--;
                neetOutMaterial.remark = "1";
                lognote lognote = new lognote()
                {
                    DateTime = DateTime.Now,
                    User = "轮询task任务",
                    Type = "轮询task任务",
                    Note = $"{neetOutMaterial.OrderNo}+{neetOutMaterial.Material.MaterialCode}+{neetOutMaterial.remark}+" +
                           $"{neetOutMaterial.Material.Consumer_MaterialId}+{taskOrder.TaskOrderCode}+{neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox.Id_Box}"
                };
                await context.AddAsync(lognote);
            }
            GlobalVariable.grouppriority--;
            await context.AddRangeAsync(taskOrders);
            await context.SaveChangesAsync();
            return new ApiResponse("分配成功", true, null);
        }
        public async Task<ApiResponse> Polling_TaskAgv_OutBound()
        {

            //plc策略
            //ushort dbint;
            //try
            //{
            //    using (S7.Net.Plc plc = new S7.Net.Plc(CpuType.S71200, "10.163.164.181", 0, 1))
            //    {
            //        plc.Open();
            //        dbint = (ushort)await plc.ReadAsync("DB112.DBW12");//读取一个int字节
            //        lognote lognote = new lognote()
            //        {
            //            Type = "Plc计数",
            //            Note = $"plc当前计数dbint:{dbint}",
            //            DateTime = DateTime.Now,
            //            User = "PlC"
            //        };
            //        await LogNote_res.InsertAsync(lognote);
            //    }

            //}
            //catch(Exception ex)
            //{
            //    dbint = 6;
            //    lognote lognote = new lognote() { 
            //        Type = "Plc错误",
            //        Note = $"plc连接失败{ex.ToString().Substring(0,150)}",
            //        DateTime = DateTime.Now,
            //        User="PlC"   
            //    };
            //    await LogNote_res.InsertAsync(lognote);
            //}

            //int IsSendCount = await context.taskOrders.Where(x => x.IsSend == true && x.Type == "出库").CountAsync();
            //if (IsSendCount + dbint > 12)
            //{
            //    lognote lognote = new lognote()
            //    {
            //        Type = "输送线满载",
            //        Note = $"输送线满载dbint-{dbint}isSendCount-{IsSendCount}",
            //        DateTime = DateTime.Now,
            //        User = "输送线"
            //    };
            //    await LogNote_res.InsertAsync(lognote);
            //    return new ApiResponse("输送线已经满载", false, null);
            //}
            //if (taskOrderquey.Count == 0)
            //{
            //    return new ApiResponse("没有需要下发的任务", false, null);
            //}
            //taskOrders.AddRange(taskOrderquey.Where(x => x.Machine_Par == 1).Take(6).ToList());
            //if (taskOrders.Count == 6)
            //{
            //    taskOrders.AddRange(taskOrderquey.Where(x => x.Machine_Par == 2).Take(6).ToList());
            //}
            //else
            //{
            //    taskOrders.AddRange(taskOrderquey.Where(x => x.Machine_Par == 2).Take(12 - taskOrders.Count()).ToList());
            //}


            //备用策略
            List<TaskOrder> taskOrderquey = await context.taskOrders.Include(x => x.Box).Where(x => x.IsSend == false
                     && x.Type == "出库" && !string.IsNullOrEmpty(x.OrderNo)&&x.OrderNo!="手动").ToListAsync();
            taskOrderquey = taskOrderquey.OrderBy(x => x.CreatTime).ToList();
            List<TaskOrder> taskOrders = new List<TaskOrder>();
            int convey1 = context.conveyorlines.Where(x => x.Machine == "1").Count();
            int convey2 = context.conveyorlines.Where(x => x.Machine == "2").Count();
            convey1 = convey1 + context.taskOrders.Where(x => x.Machine == 1 && x.Type == "出库" && x.IsSend == true).Count();
            convey2 = convey2 + context.taskOrders.Where(x => x.Machine == 2 && x.Type == "出库" && x.IsSend == true).Count();
            if (convey1 > 9)
            {
                convey1 = 9;
            }
            if (convey2 > 9)
            {
                convey2 = 9;
            }
            taskOrders.AddRange(taskOrderquey.Where(x => x.Machine == 1).Take(9 - convey1).ToList());
            taskOrders.AddRange(taskOrderquey.Where(x => x.Machine == 2).Take(9 - convey2).ToList());
            lognote lognoteconvey = new lognote()
            {
                Type = "输送线状态",
                Note = $"输送线状态1号台:{9 - convey1}2号台:{9 - convey2}",
                DateTime = DateTime.Now,
                User = "输送线"
            };
            await context.AddAsync(lognoteconvey);
            //上面策略后加
            foreach (var taskOrder in taskOrders)
            {
                Ess_Input ess_Input = new Ess_Input();
                ess_Input.taskType = "carry";
                ess_Input.taskGroupCode = $"taskGroupCode-{taskOrder.taskPriority}";
                ess_Input.groupPriority = taskOrder.groupPriority;
                List<Tasks> data = new List<Tasks>();
                Tasks ta = new Tasks();
                ta.taskCode = taskOrder.TaskOrderCode;
                ta.taskPriority = taskOrder.taskPriority;
                data.Add(ta);
                ess_Input.tasks = data;
                TaskDescribe td = new TaskDescribe();
                td.containerCode = taskOrder.Box.BoxCode;
                td.containerType = "CT_KUBOT_STANDARD";
                td.storageTag = "";
                td.fromLocationCode = "";//taskOrder.WarehouseCode
                td.toLocationCode = taskOrder.InlethouseCode;
                td.toStationCode = "haiport_station_1";
                td.isPutaway = false;
                ta.taskDescribe = td;
                string res = await toOutSideInterFace.CreateTask(ess_Input);
                if (res.Contains("OK"))
                {
                    taskOrder.State = "已下发";
                    taskOrder.IsSend = true;
                    taskOrder.Box.Machine = taskOrder.Machine.ToString();
                    lognote lognote = new lognote() { Type = "下架", Note = $"轮询了下架任务{taskOrder.Box.BoxCode}-{taskOrder.WarehouseCode}-{taskOrder.InlethouseCode}" };
                }
                else
                {
                    lognote lognote = new lognote() { Type = "下架", Note = $"任务发送失败：{res}{taskOrder.Box.BoxCode}-{taskOrder.WarehouseCode}-{taskOrder.InlethouseCode}" };
                }
            }
            await context.SaveChangesAsync();
            return new ApiResponse("轮询成功", true, null);
        }//轮询发送Agv任务
        public async Task<ApiResponse> Polling_UpdateQuantity()//轮询核对虚拟数量
        {
            var neet = await context.neetOutMaterials.ToListAsync();
            if (neet.Count > 0)
            {
                lognote lognote2 = new lognote()
                {
                    DateTime = DateTime.Now,
                    User = "hangfile",
                    Type = "hangfile",
                    Note = ($"有料未拣配")
                };
                await context.AddAsync(lognote2);
                await context.SaveChangesAsync();
                return new ApiResponse($"有料未拣配", false, null);
            }

            var materials = await context.materialBases.Where(x => x.Quantity != x.VirtualQuantity && x.BoxPosition.TheBoxGrid.TheBox.WarehouseLine != null).ToListAsync();
            materials.ForEach(x => x.VirtualQuantity = x.Quantity);
            lognote lognotetasknull = new lognote()
            {
                DateTime = DateTime.Now,
                User = "hangfile",
                Type = "hangfile",
                Note = ($"")
            };
            await context.AddAsync(lognotetasknull);
            await context.SaveChangesAsync();
            return new ApiResponse($"修改成功", true, null);

        }
        public async Task<ApiResponse> Polling_ClearConveyorline()//轮询清理输送线/清理日志
        {
            var conveyorlines = await context.conveyorlines.ToListAsync();

            DateTime tenDaysAgo = DateTime.Now.AddDays(-10);
            var logs = await context.lognotes.Where(x => x.DateTime <= tenDaysAgo&&x.Type!="入库"&& x.Type != "出库").ToListAsync();

            context.RemoveRange(logs);
            context.RemoveRange(conveyorlines);

            lognote lognote = new lognote()
            {
                DateTime = DateTime.Now,
                User = "清理成功",
                Type = "清理成功",
                Note = ($"清理成功")
            };
            await context.SaveChangesAsync();
            return new ApiResponse("清理成功", true, null);
        }
        public async Task<ApiResponse> Polling_expireTaskOrder()//轮询过期任务
        {
            var halfHourAgo = DateTime.Now.AddMinutes(-30);
            TaskOrder taskorder = await TaskOrder_res.FirstOrDefaultAsync(x => x.CreatTime <= halfHourAgo && x.IsSend == true && x.Type == "入库");
            if (taskorder == null)
            {
                return new ApiResponse("无过期任务", true, null);
            }
            Box box = await context.boxs.FirstOrDefaultAsync(x => x.Id_Box == taskorder.Id_Box);
            string EssWarehouline = await toOutSideInterFace.queryContainer(box.BoxCode);
            if (!EssWarehouline.Contains("HAI")|| EssWarehouline !=taskorder.WarehouseCode)
                {
                lognote lognote = new lognote()
                {
                    DateTime = DateTime.Now,
                    User = "轮询",
                    Type = "轮询-料盒未上架/或者库位不符合",
                    Note = $"{taskorder.TaskOrderCode}"
                };
                await LogNote_res.InsertAsync(lognote);
                return new ApiResponse("ESS检查料盒已上架,请核对库位", false, null);
                }
                InPut_EssService InPut = new InPut_EssService();
                InPut.taskCode = taskorder.TaskOrderCode;
                InPut.eventType = "task";
                InPut.status = "success";
                if (InPut.eventType == "task")
                {
                    if (InPut.status.Contains("success"))
                    {
                        TaskOrder taskOrder = await context.taskOrders.FirstOrDefaultAsync(x => x.TaskOrderCode == InPut.taskCode);
                        if (taskOrder == null)
                        {
                            return new ApiResponse("未查询处理过期任务", true, null);
                        }
                        if (taskOrder.Type == "入库")
                        {
                            //excuting
                            WarehouseLine warehouseLine = await context.warehouseLines.FirstOrDefaultAsync(x => x.WarehouseLineCode == taskOrder.WarehouseCode);
                            box.Id_WarehouseLine = warehouseLine.Id_WarehouseLine;
                            box.WarehouseLine = warehouseLine;
                            context.taskOrders.Remove(taskOrder);
                            //备用
                            Conveyorline conveyorline = await context.conveyorlines.FirstOrDefaultAsync(x => x.BoxCode == box.BoxCode);
                            if (conveyorline != null)
                            {
                                context.conveyorlines.Remove(conveyorline);
                            }
                            lognote lognote = new lognote()
                            {
                                DateTime = DateTime.Now,
                                User = "轮询",
                                Type = "轮询过期任务",
                                Note = $"{taskOrder.TaskOrderCode}"
                            };
                            await context.AddAsync(lognote);
                            await context.SaveChangesAsync();
                        }
                    }                   
                }
                return new ApiResponse("已处理过期任务", true, null);
        }
        public async Task Handle(PostNotification notification, CancellationToken cancellationToken)//数量为0物料 清空
        {

            MaterialBase materialbases =await MaterialBase_res.FirstOrDefaultAsync(x => x.Quantity == 0&&x.Consumer_MaterialId== notification.Body);
            if (materialbases != null)
            {
                if (materialbases.Quantity == 0)
                {
                    await MaterialBase_res.DeleteAsync(materialbases);
                    lognote lognote = new lognote()
                    {
                        DateTime = DateTime.Now,
                        User = "物料清零",
                        Type = "物料清零",
                        Note = $"{notification.Body}"
                    };
                    await LogNote_res.InsertAsync(lognote);
                }
            } 
     
           

        }

        public Task<ApiResponse> Polling_ClearEmpty()
        {
            throw new NotImplementedException();
        }
    }
}
